一、事务回滚问题
1、查看源码发现,事务默认是只回滚运行时异常,如果没有配置,则对非运行时异常不会回滚
例如: @Transactional注解后面配置了rollbackFor = Throwable.class,则对所有异常都会回滚
如果没有配置,则不会回滚非运行时异常
@Transactional(rollbackFor = Throwable.class)
public void save(User user, boolean flag) throws Exception {
userMapper.insertSelective(user);
if (flag) {
throw new Exception();
}
}
二、事务失效问题
1、Spring中一个没有事务的方法调用一个有事务的方法,会导致事务失效,
2、原因是代理对象只会作用于目标对象调用的那个方法,不会作用于其它方法
3、如果springmvc配置了全扫描包,也会导致事务失效。
三、事务失效的解决办法
方式一:自己手动创建事务,提交事务,回滚事务(Springboot中测试)
@Service
public class UserService {
@Autowired
protected UserMapper userMapper;
@Autowired
private DataSourceTransactionManager transactionManager;
public void test(User user, boolean flag) throws Exception {
save(user, flag);
}
public void save(User user, boolean flag) {
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transaction = transactionManager.getTransaction(definition);
try {
userMapper.insertSelective(user);
if (flag) {
throw new Exception();
}
transactionManager.commit(transaction);
} catch (Exception e) {
transactionManager.rollback(transaction);
}
}
}
方式二:获取代理类对象,使用代理类对象调用带有事务的方法(Springboot中测试)
@Service
public class UserService {
@Autowired
protected UserMapper userMapper;
@Autowired
private ApplicationContext applicationContext;
public void test(User user, boolean flag) throws Exception {
//获取代理类对象
UserService bean = applicationContext.getBean(UserService.class);
//由代理类对象调用带有事务的方法
bean.save(user, flag);
}
@Transactional(rollbackFor = Throwable.class)
public void save(User user, boolean flag) {
try {
userMapper.insertSelective(user);
if (flag) {
throw new Exception();
}
} catch (Exception e) {
//捕获异常,获取当前事务的状态,然后手动回滚,如果没有事务,则会抛出异常
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}