下面简单介绍下,spring中常见的事务失效的几种情况。让我们在开发的过程避免这些情况,写出正确而且优雅的代码。
文章目录
数据库引擎不支持,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中事务失效的常见几种情况。