事务一致性的测试

框架:spring

数据库:innodb

代码地址

spring事务的串行化

isolation=Isolation.SERIALIZABLE

  • 多个串行化事务发生冲突会抛出死锁异常

  • 串行化和不可重复读发生冲突的情况

事务1:串行化

事务2:不可重复读(默认隔离级别)

执行顺序结果
1开启 - 2开启 - 2结束 - 1结束事务1正常,事务2发生死锁异常
1开启 - 2开启 - 1结束 - 2结束事务2的操作覆盖了事务1的操作
2开启 - 1开启 - 1结束 - 2结束事务2的操作覆盖了事务1的操作
2开启 - 1开启 - 2结束 - 1结束事务1正常,事务2发生死锁异常

总结:

  1. 事务1开启时给数据上锁,具体哪种锁没有研究
  2. 如果事务2先结束,提交事务时由于事务1没有释放锁,所以会发生死锁异常,这种结果可以保证一致性
  3. 如果事务2后结束,提交事务时事务1已经释放了锁,事务2使用旧数据更新数据库导致数据不一致

排他锁(悲观锁)

前提:需要保证一致的逻辑在一个事务中

先申请排他锁

加锁:select … for update

例如:

SELECT id, value
FROM t_pessimistic
WHERE id = 1
FOR UPDATE

会对查询结果的每行加排他锁

如果没有其他事务对查询结果中的任一行使用排他锁时可以成功获得锁,否则会阻塞直到获得锁

如果发生冲突的几率较低,每次都加锁会产生额外开销

适合发生冲突几率高的情况

乐观锁

代码中实现的乐观锁好像不太稳定

给需要保证一致性的表增加版本号字段

每次执行update或delete时,验证版本号,如果不一致就重试

如果发生冲突的几率较高,可能会重试多次,反而影响效率

适合发生冲突几率低的情况

总结

要保证数据的一致性,同一个表应该使用同一种锁

欢迎补充

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值