Spring @Transactional传播无效

时间:2017-04-11 10:38:06

标签: spring hibernate transactions spring-transactions transactional

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

服务层: -

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
 }
}

ReqProcessor层: -

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);
 }
}

DAO层: -

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)

我在注释行中收到以下异常:

pd.DataFrame

当删除抽象类时,代码工作得非常好,只剩下接口及其实现类。但是通过上面的设置,事务不会从ReqProcessor层传播到DAO层。请帮忙。 (别介意各地的公共访问者,它只是用于测试) 我也搜索了SO和其他论坛,但无法找到解决方案。

1 个答案:

答案 0 :(得分:2)

正如@m-deinum所提到的,Spring使用代理来添加“事务”功能,当您从类的另一个方法调用使用@Transactional注释的方法时,此功能不起作用。

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

  1. AbstractReqProcessor autowire ApplicationContext中,然后使用它来获取CustomHibernateDao类型的bean。在此检索到的对象上,您可以调用saveObject - 然后transactional魔法发生。
  2. 更优选的方法是使用saveOrUpdate注释对类AbstractService的方法@Transactional进行注释 - 然后它将再次起作用。
  3. 但我认为你现在知道问题的原因,你可以找到另一个 - 更适合你的方式。