SpringBoot中的事务配置
Spring Boot事务配置管理
事务相关
事务的作⽤就是为保证⽤户的每⼀个操作都是可靠的,事务中的每⼀步操作都必须成功执⾏,只要有发⽣异常就回退到事务开始未进⾏操作的状态。这很好理解,转账、购票等等,必须整个事件流程全部执⾏完才能⼈为该事件执⾏成功,不能转钱转到⼀半,系统死了,转账⼈钱没了,收款⼈钱还没到。
Spring Boot事务配置
1. 依赖导⼊
导⼊依赖之后会⾃动注⼊DataSourceTransactionManager ⽆需其他配置就可使⽤@Transactional注解进⾏事务的使⽤l。
2. 简单测试(略)
springframework事务3. 常见问题:
1. 异常未被捕获到的情况
⽰例代码:
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
@Transactional
public void isertUser2(User user) throws Exception {
// 插⼊⽤户信息
userMapper.insertUser(user);
/
/ ⼿动抛出异常
throw new SQLException("数据库异常");
}
}
上⾯这个代码,其实并没有什么问题,⼿动抛出⼀个 SQLException 来模拟实际中操作数据库发⽣的异常,在这个⽅法中,既然抛出了异常,那么事务应该回滚,实际却不如此。
因为 Spring Boot 默认的事务规则是遇到运⾏异常(RuntimeException)和程序错误(Error)才会回滚。⽐如上⾯我们的例⼦中抛出的 RuntimeException 就没有问题,但是抛出SQLException 就⽆法回滚了。针对⾮运⾏时异常,如果要进⾏事务回滚的话,可以在@Transactional 注解中使⽤ rollbackFor 属性来指定异常,⽐如 @Transactional(rollbackFor = Exception.class) ,这样就没有问题了,所以在实际项⽬中,⼀定要指定异常。
2. 异常被 ”吃“ 掉的情况
在处理异常时,有两种⽅式,要么抛出去,让上⼀层来捕获处理;要么把异常 try catch 掉,在异常出现的地⽅给处理掉。就因为有这种 atch,所以导致异常被 ”吃“ 掉,事务⽆法回滚。
解决办法:直接往上抛,给上⼀层来处理即可,千万不要在事务中把异常⾃⼰ ”吃“ 掉
3. 事务的范围
并发场景下,⽅法上加了@Transactional,⽅法内部使⽤synchronized关键字,该⽅法执⾏,事务启动,整个⽅法执⾏结束,事务关闭。出现问题的原因是:因为事务的作⽤范围⽐锁的范围⼤,也就是说,在加锁的那部分代码执⾏完之后,锁释放掉了,但是事务还没结束,此时另⼀个线程进来了,事务没结束的话,第⼆个线程进来时,数据库的状态和第⼀个线程刚进来是⼀样的。即由于mysql Innodb引擎的默认隔离级别是可重复读(在同⼀个事务⾥,SELECT的结果是事务开始时时间点的状态),线程⼆事务开始的时候,线程⼀还没提交完成,导致读取的数据还没更新。第⼆个线程也做了插⼊动作,导致了脏数据。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。