下面代码中:
@Service
public class AddressService {
@Autowired
AddressMapper addressMapper;
@Transactional(rollbackFor =Exception.class)
public void errorInvoker(Address address){
addressMapper.insert(address);
}
}
在Service中标记了一个@Transactional,采用的默认传播机制。
在此期间回顾:
在使用注解@Transactional会导致事务回滚失败的方式有以下常见的几种:
没有开启事务管理器
没有被Bean容器管理
数据库引擎不支持
事务多线程调用
错误的事务传播机制
异常被捕获并处理
报错信息就是:Transaction rolled back because it has been marked as rollback-only
,很好理解:事务被回滚了,因为它已经被标记了只能回滚
以下就是大致代码:
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean xxx(xxx dto) {
list1 = .....;
try {
数据库批量保存list1;
} catch (Exception e) {
if (e instanceof DuplicateKeyException) {
//过滤重复 key 的数据
数据库批量保存过滤之后的list1;
}
....
}
list2 = .....;
try {
数据库批量保存list2;
} catch (Exception e) {
if (e instanceof DuplicateKeyException) {
//过滤重复 key 的数据
数据库批量保存过滤之后的list2;
}
...
}
return Boolean.TRUE;
}
以下是Service层自带的
这时候就会发现,代码完美的实现的嵌套事务功能,这就导致报:
Transaction rolled back because it has been marked as rollback-only
回顾事务传播机制:
解决方案:
①删除自己方法上的注解@Transactional
②修改事务传播机制
③写SQL批量插入
④mybatis-plus也提供了另一种批量查出,如下图: