spring中事务失效的几种情况

下面简单介绍下,spring中常见的事务失效的几种情况。让我们在开发的过程避免这些情况,写出正确而且优雅的代码。

文章目录

  • 数据库引擎不支持,mysql需要InnoDB
  • 方法必须是public的
  • 方法必须是被其他类调用
  • 业务方法中异常被try-catch掉,导致异常没有抛出,没有触发回滚,事务失效
  • 打上事务注解的方法所在的类并没有交给spring的IOC容器管理,同样会导致事务失效
  • @Transitional默认是捕获运行时异常(继承RuntimeException)才回滚,所以如果想要捕获所有异常都回滚,需要在@Transitional后面加上(rollbackFor=Exception.class)
  • 本文小结

数据库引擎不支持,mysql需要InnoDB

MySQL的MyISAM引擎是不支持事务操作的,InnoDB引擎才支持事务。


方法必须是public的

@Transactional(rollbackFor = Exception.class)
    protected  int batchAdd(List<Role> roleList) {
        int i = roleMapper.insertList(roleList);
        Integer a = null;
        a.toString();
        return  i;
    }

方法必须是被其他类调用

自身调用问题,业务层自身非事务方法调用事务方法,会导致不经过Spring的代理类。默认只有在外部调用事务方法,事务才会生效。

@Service 
public class RoleServiceImpl implements RoleService {

    @Transactional(rollbackFor = Exception.class)
    public int batchAdd(List<Role> roleList) {
        int i = roleMapper.insertList(roleList);
        Integer a = null;
        a.toString();
        return  i;
    }
     public int testBatchAdd(List<Role> roleList){
      return  batchAdd(roleList);
   }
}

class Test{

    @Autowired
    RoleServiceImpl service;
    @Test
    public void test() {
        Role role = new Role();
        role.setRoleName("sss");
        role.setRemark("哈哈哈");
        Role role2 = new Role();
        role.setRoleName("bbb");
        role.setRemark("嘿嘿嘿");
        List<Role> roleList = new ArrayList<>();
        roleList.add(role);
        roleList.add(role2);
        int i = service.testBatchAdd(roleList);

    }
}

业务方法中异常被try-catch掉,导致异常没有抛出,没有触发回滚,事务失效

需要抛出异常,才会回滚,如果你已经自己把异常捕获了,但是没有继续往外抛,那么也是不会回滚的。

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int batchAdd(List<Role> roleList) {
        int i = roleMapper.insertList(roleList);
        try {
            Integer a = null;
            a.toString();
        }catch (Exception e){
           //todo something
        }
        return  i;
    }

打上事务注解的方法所在的类并没有交给spring的IOC容器管理,同样会导致事务失效

// @Service 注释掉@Service注解,此类就没有交给Spring管理
public class RoleServiceImpl implements RoleService {

    @Transactional(rollbackFor = Exception.class)
    public int batchAdd(List<Role> roleList) {
        int i = roleMapper.insertList(roleList);
        Integer a = null;
        a.toString();
        return  i;
    }
    
}

@Transitional默认是捕获运行时异常(继承RuntimeException)才回滚,所以如果想要捕获所有异常都回滚,需要在@Transitional后面加上(rollbackFor=Exception.class)

业务方法中的运行时异常被try-catch之后,在catch里面抛出的异常类型不是运行时异常,同样会导致事务失败,因为如果不在事务注解中声明触发回滚类型,默认的是RuntimeException。

    @Transactional
    @Override
    public int batchAdd(List<Role> roleList) throws MyException {
        int i = 0;
        try {
            i = roleMapper.insertList(roleList);
            Integer a = null;
            a.toString();
        }catch (Exception e){
            throw new MyException("xxx错误");
        }
        return  i;
    }

本文小结

本文简单介绍了spring中事务失效的常见几种情况。

你可能感兴趣的:(spring核心知识,web后端,数据库,spring)