欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

事务一致性的测试

程序员文章站 2022-03-03 20:00:31
...

框架: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时,验证版本号,如果不一致就重试

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

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

总结

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

欢迎补充

相关标签: 事务 数据库锁