事务相关的问题总结

一、事务回滚问题

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

你可能感兴趣的:(事务相关的问题总结)