Spring @Transactional传播不起作用 [英] Spring @Transactional propagation is not working

查看:193
本文介绍了Spring @Transactional传播不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的代码,其中包括Service-> RequestProcessor-> DAO,每层中都有2-3个类(接口,抽象,具体).

I have a very simple code comprising of Service -> RequestProcessor -> DAO having 2-3 classes (interface, abstract, concrete) in each layer.

服务层:-

public interface Service {
   public void saveOrUpdate(Object entity, String operationName);
 }
}

public abstract class AbstractService implements Service{

   public abstract ReqProcessor getRP();
   @Override
   public void saveOrUpdate(Object entity, String operationName) {
     ReqProcessor hiberTestRP = getRP();
     hiberTestRP.saveOrUpdate(entity, operationName);
 }
}

@Component
public class ServiceImpl extends AbstractService {

  @Autowired
  public ReqProcessor hibertestRPImpl;

  @Override
  public HiberTestRP getRP() {
    return hibertestRPImpl;
 }
}

ReqProcessor层:-

ReqProcessor layer:-

public interface ReqProcessor {
   public void saveOrUpdate(Object entity, String operationName);
   public void saveObject();
 }
}

public abstract class AbstractReqProcessor  implements ReqProcessor {
@Override
public void saveOrUpdate(Object entity, String operationName) {
    saveObject();
 }
}

@Component
public class ReqProcessorImpl extends AbstractReqProcessor {
 @Autowired
 public CustomHibernateDao customWSDaoImpl;

 @Override
 @Transactional(value="transactionManagerWS", propagation=Propagation.REQUIRED)
 public void saveObject() {
  // object created //
  customWSDaoImpl.saveOrUpdate(object);  // exception is thrown at this line
 }
}

DAO层:-

public interface CustomHibernateDao {
  public void saveOrUpdate(Object entity, String operationName);
}

@Repository
@Transactional(value="transactionManagerWS", propagation=Propagation.MANDATORY)
public class CustomWSDaoImpl implements CustomHibernateDao {

 @Autowired
 public SessionFactory sessionFactoryWS;

 protected Session getCurrentSession() {
    return sessionFactoryWS.getCurrentSession();
 }

 @Override
 public void saveOrUpdate(Object entity, String operationName) {
    Session session = getCurrentSession();
    session.saveOrUpdate(entity);
 }
}

我在注释行得到以下异常:

I get the following exception at the commented line :

Exception in thread "main" org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:359)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:447)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:277)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy37.saveOrUpdate(Unknown Source)

当删除抽象类时,该代码绝对可以正常工作,仅保留接口及其实现类.但是,使用上述设置,不会将事务从ReqProcessor层传播到DAO层.请帮忙. (不要介意到处都是公共"访问器,这只是为了测试) 我也在SO和其他论坛上进行了搜索,但找不到解决方案.

The code works absolutely fine when the abstract classes are removed, with only interfaces and their implementing classes remaining. But with the above setup, the transaction is not being propagated from ReqProcessor layer to the DAO layer. Please help. (Dont mind the 'public' accessors everywhere, it's just for testing) I have also searched on SO and other forums but couldnt find a solution.

推荐答案

如@ m-deinum所述,Spring使用代理添加事务"功能,并且当您调用带有@Transactional注释的方法时,此功能不起作用来自该类的另一种方法.

As @m-deinum has mentioned, Spring uses proxies to add "transactional" functionality, and this feature does not work when you call method annotated with @Transactional from another method of the class.

您有两种方法可以解决此问题:

You have two ways to fix the problem:

  1. AbstractReqProcessor中自动装配ApplicationContext,然后使用它获取CustomHibernateDao类型的Bean.在此检索到的对象上,您可以调用saveObject-然后发生transactional魔术.
  2. 更优选的方法是也使用@Transactional注释对AbstractService类的方法saveOrUpdate进行注释-然后它将再次起作用.
  1. In AbstractReqProcessor autowire ApplicationContext and then use it to get a bean of CustomHibernateDao type. On this retrieved object you can call saveObject - then the transactional magic happens.
  2. The more preferred way is to annotate method saveOrUpdate of class AbstractService with @Transactional annotation too - then it will work again.

但是我认为您现在已经知道了问题的原因,您可以找到另一种-更适合您的方式-

But I think you know the cause of the problem now and you can find another - more suitable for you - way.

这篇关于Spring @Transactional传播不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆