Spring中的Service方法如果声明了事务,例如@Transactional(propagation = Propagation.REQUIRED),那么调用的时候,Spring会自动管理事务,遇到Exception,会rollback回滚,但是可能会遇到这种情况:同一个Service类中的方法,要调用本类中的其他方法(尽管这个方法也声明了事务),会发现调用的那个方法没有开启事务。
Spring开启事务,需要两个条件
- 首先需要方法声明是public的
- 声明事务,可以是在Service上加@Transactional或者方法上加@Transactional
- 需要从其他类中调用(不能是本类直接调用)
解决办法
- 方式1
在本Service里,内部用注解加一个自身的的service
@Service("systemService")
@Transactional(readOnly = false)
@Repository
public class SystemServiceImpl implements ISystemService {
@Resource(name = "systemService")
ISystemService selfReference;
private void doSomeAndThenMore() {
// 这样做实现事务管理
selfReference.doSometingTransaction();
// 如果要让里面的方法实现事务处理,不能这样直接调用:this.doSometingTransaction()
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doSometingTransaction() {
// 一些处理逻辑以及数据库操作等,可能涉及到事务
}
}
- 方式2
在同一个service中,调用的时候,使用applicationContext.getBean(this.getClass()).someMethod(),如下:
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class TransactionServiceDemo {
@Autowired
private ApplicationContext applicationContext;
private TransactionServiceDemo getSpringProxy() {
return applicationContext.getBean(this.getClass());
}
private void doSomeAndThenMore() {
// 这样做实现事务管理
getSpringProxy().doSometingTransaction();
// 如果要让里面的方法实现事务处理,不能这样直接调用:this.doSometingTransaction()
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doSometingTransaction() {
// 一些处理逻辑以及数据库操作等,可能涉及到事务
}
}
文章评论