Spring @Transactional 传播无效
Spring @Transactional propagation is not working
我有一个非常简单的代码,由 Service -> RequestProcessor -> DAO 组成,每层有 2-3 类(接口、抽象、具体)。
服务层:-
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 层:-
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);
}
}
我在注释行得到以下异常:
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 层。请帮忙。 (不要介意到处都是 'public' 访问器,它只是为了测试)
我也在 SO 和其他论坛上搜索过,但找不到解决方案。
正如@m-deinum 提到的,Spring 使用代理来添加 "transactional" 功能,当您从另一个方法调用带有 @Transactional
注释的方法时,此功能不起作用class.
您有两种解决问题的方法:
- 在
AbstractReqProcessor
中自动装配ApplicationContext
,然后用它来获取CustomHibernateDao
类型的bean。在这个检索到的对象上,您可以调用 saveObject
- 然后 transactional
魔法就会发生。
- 更好的方法是用
@Transactional
注释来注释classAbstractService
的方法saveOrUpdate
——然后它会再次起作用。
但我想你现在知道问题的原因了,你可以找到另一个更适合你的方法。
我有一个非常简单的代码,由 Service -> RequestProcessor -> DAO 组成,每层有 2-3 类(接口、抽象、具体)。
服务层:-
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 层:-
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);
}
}
我在注释行得到以下异常:
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 层。请帮忙。 (不要介意到处都是 'public' 访问器,它只是为了测试) 我也在 SO 和其他论坛上搜索过,但找不到解决方案。
正如@m-deinum 提到的,Spring 使用代理来添加 "transactional" 功能,当您从另一个方法调用带有 @Transactional
注释的方法时,此功能不起作用class.
您有两种解决问题的方法:
- 在
AbstractReqProcessor
中自动装配ApplicationContext
,然后用它来获取CustomHibernateDao
类型的bean。在这个检索到的对象上,您可以调用saveObject
- 然后transactional
魔法就会发生。 - 更好的方法是用
@Transactional
注释来注释classAbstractService
的方法saveOrUpdate
——然后它会再次起作用。
但我想你现在知道问题的原因了,你可以找到另一个更适合你的方法。