下面我将详细讲解“spring声明式事务 @Transactional 不回滚的多种情况以及解决方案”。
RuntimeException
及其子类异常时,才会导致事务回滚。Exception
的异常),Spring不会自动回滚。@Transactional
是基于AOP实现的,因此同一个类中的方法调用,不会触发事务回滚。原因是在一个事务方法内部调用另外一个有@Transactional
注解的方法,Spring框架并不会再次开启一个新的事务,而是继续使用已经存在的事务。因此即使另一个方法抛出异常,也不会影响当前事务的提交或回滚。@Transactional
注解的rollbackFor
属性来指定异常回滚的类型,如@Transactional(rollbackFor = Exception.class)
,这样就可以把受检异常也包含进回滚的规则中,实现更加灵活的回滚控制。@Transactional
注解的方法时,通过Propagation.REQUIRES_NEW
参数来指定该方法必须开启新的事务,例如:```java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
@Transactional
public void updateUser(User user) {
userMapper.updateUser(user);
// 更新用户信息后需要往用户日志表中插入一行新纪录
this.insertUserLog(user);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertUserLog(User user) {
UserLog userLog = new UserLog();
userLog.setUserId(user.getUserId());
userLog.setOperateType("update");
userMapper.insertUserLog(userLog);
}
}
```
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
来手动设置回滚状态。例如:java
@Override
@Transactional
public void updateUser(User user) {
try {
userMapper.updateUser(user);
throw new RuntimeException("test");
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw e;
}
}
TransactionAspectSupport.currentTransactionStatus().hasRollbackOnly()
方法来判断当前事务是否已经回滚,如果已经回滚,则需要重新抛出异常,例如:java
@Override
@Transactional
public void updateUser(User user) {
try {
userMapper.updateUser(user);
throw new RuntimeException("test");
} catch (Exception e) {
if (TransactionAspectSupport.currentTransactionStatus().hasRollbackOnly()) {
throw e;
}
// ...处理异常
}
}
好了,这就是关于“spring声明式事务 @Transactional 不回滚的多种情况以及解决方案”的完整攻略。希望对你有所帮助。
本文链接:http://task.lmcjl.com/news/19005.html