1. 数据库引擎不支持事务
以 MySQL 为例,MyISAM存储引擎不支持事务, InnoDB 引擎支持事务。
2. 异常被catch
执行以下测试方法,数据成功插入,调用 test 方法没有回滚。
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void test(CustomerDO customerDO) {
mapper.insert(customerDO);
try {
int i = 1 / 0;
} catch (Exception e) {
log.info("", e);
}
}
3. 异常抛出类型错误
异常抛出类型错误,事务回滚的默认级别是 RuntimeException,抛出的异常必须是 RuntimeException 或它的子类。
抛出的异常是 RuntimeException 时,调用 test 方法回滚成功:
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void test(CustomerDO customerDO) throws Exception {
mapper.insert(customerDO);
throw new RuntimeException("234334334");
}
抛出的异常是 Exception 时,是RuntimeException的父类,不被识别,调用 test 方法回滚失败:
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void test(CustomerDO customerDO) throws Exception {
mapper.insert(customerDO);
throw new Exception("234334334");
}
解决办法,指定回滚的异常 rollbackFor = Exception.class,调用 test 方法回滚成功:
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void test(CustomerDO customerDO) throws Exception {
mapper.insert(customerDO);
throw new Exception("234334334");
}
4. 本类方法调用
本类方法调用,会用 this 关键字,没有经过Spring的代理类去调用此方法。
如下使用this关键字,调用 test 方法回滚失败:
@Override
public void test(CustomerDO customerDO) throws Exception {
test1(customerDO);
}
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void test1(CustomerDO customerDO) throws Exception {
mapper.insert(customerDO);
int i = 1 / 0;
}
如下调用 test 方法回滚成功,REQUIRES_NEW 失效:
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void test(CustomerDO customerDO) throws Exception {
test1(customerDO);
int i = 1 / 0;
}
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void test1(CustomerDO customerDO) throws Exception {
mapper.insert(customerDO);
}
5. 没有被Spring管理
没有被Spring管理,无法使用Spring的事务,事务自然不起作用。
一般工程中不会有这种错误,一般 Service 方法是注入到 Controller 里面的。