firebird 行级锁问题_详解:共享锁、排它锁与事务隔离级别的关系
发布日期:2021-06-24 13:02:35 浏览次数:2 分类:技术文章

本文共 1375 字,大约阅读时间需要 4 分钟。

4b14b863a20627375074b11420ffe4b3.png

共享锁、排他锁

InnoDB 实现了两种类型的锁机制:共享锁(S)和排他锁(X)。共享锁允许一个事务读数据,不允许修改数据,如果其他事务要再对该行加锁,只能加共享锁;排他锁是修改数据时加的锁,可以读取和修改数据,一旦一个事务对该行数据加锁,其他事务将不能再对该数据加任务锁。

9565f00737072d24ca3c1a4350db11f5.png

x轴:事务A拥有的锁 y轴:事务B申请的锁

:一个事务在某一行数据上加上排它锁后,其他事务不能再在这行数据加任何锁,无法进行 update 与 delete,但是普通的 select 是可以的,因为普通的 select 不加任何锁,当 select .... from ... for update 时才会加上排它锁。

并发事务带来的问题

1.数据丢失(两个事务同时修改一行数据,其中一个事务异常回滚,导致更新失败)

4027f298e3614fda9dcdea6bb07c4d8d.png

解决办法:未提交读(Read Uncommitted):在事务 B 读取数据时,事务 A 读取数据加了共享锁,修改数据时加了排它锁。这种隔离级别,会导致脏读、不可重复读以及幻读。

b0d8e83119d2d3893850bb536d03c206.png

未提交读会导致脏读、不可重复读、幻读的原因:尽管 A 持有排它锁,避免了两个事务同时修改的情况,但是普通的 select 不持有锁,还是可以读到数据的,所以事务 A 多次修改数据,事务 B 中的查询还是可以看到的。

2.脏读(一个事务的执行期间,另一个事务读到了没有提交数据)

25cb5a1a33515c2c8765dfcd92a7be88.png

解决办法:已提交读(Read Committed):在事务 B 读取数据时增加了共享锁,一旦读取,立即释放锁,事务 A 读取修改数据时增加了行级排他锁,直到事务结束才释放锁。 也就是说,事务 B 在读取数据时,事务 A 只能读取数据,不能修改。当事务 B 读取到数据后,事务 A 才能修改。 这种隔离级别,可以避免脏读,但依然存在不可重复读以及幻读的问题。

cee98f2fadeca53676f27727188653e5.png

已提交读会导致不可重复读、幻读的原因:事务 B 没有提交就将锁释放,导致事务 A 可以对数据进行任意修改,修改后,事务 B 再次获取共享锁查询,查询到跟之前读取不一致的数据。

3.不可重复读(一个事务的执行期间,另一个事务连续两次读取到的值不一样)

a53299f631c49d41043ef36283ad8cbf.png

解决办法:可重复读(Repeatable Read):在事务 B 读取数据时增加了共享锁,事务结束,才释放锁,事务 A 读取修改数据时增加了行级排他锁,直到事务结束才释放锁。 也就是说,事务 B 在没有结束事务时,事务 A 只能读取数据,不能修改。当事务 B 结束事务,事务 A 才能修改。 这种隔离级别,可以避免脏读、不可重复读,但依然存在幻读的问题。

a700639d8ff6491875c666f66d1fb08d.png

可重复读导致幻读的原因:可重复读是加的行级锁,而幻读是满足查询条件的前提下数据量发生变化,即发生 insert 或 delete操作。

4.幻读(一个事务的执行期间,另一个事务连续两次读取到的数量不同)

f6528d73e9e963f33769a82f7a292738.png

解决办法:可序列化(Serializable):在事务 A 读取数据时增加了共享锁,事务结束,才释放锁,事务 B 读取修改数据时增加了表级排他锁,直到事务结束才释放锁。

可序列化解决了脏读、不可重复读、幻读等问题,但隔离级别越来越高的同时,并发性会越来越低。

f53b555bd66b1a84aa8a0781c8882ce8.png

小结

可以看出,控制数据库并发带来的问题依赖的是锁粒度的扩大来解决的。

但是隔离级别越大,并发性就越差,如果业务场景允许的情况下,适当减小隔离级别是处理并发的一种手段。

转载地址:https://blog.csdn.net/weixin_32905035/article/details/113072024 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:mysql 匹配字符_MySQL中的字符串模式匹配
下一篇:echart用data实现所有图表_抖音很火的动态条图表怎么做?5分钟让你get到!

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月13日 14时33分53秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

java中非静态、静态方法的调用、方法中调用方法 2019-04-28
Java中的访问权限修饰符、各种变量、static、final等关键字,一直混淆的整理(未完) 2019-04-28
宋红康的快捷键包描述(idea导入类似eclipse的)keymap-shkstart.jar 2019-04-28
IDEA默认的快捷键整理!! 2019-04-28
超宽带雷达P440?雷达的快时间慢时间是什么意思? 2019-04-28
教育授权certificate used to sign the license 2019-04-28
从内存解释:方法传参(基本数据类型、引用数据类型(对象、数组、String类型)),原值是否改变? 2019-04-28
java中数组为空和数组长度为0的区别 2019-04-28
SecureCRT连接不上虚拟机 2019-04-28
为什么在创建线程时,更推荐用实现Runnable接口的方法?而不是继承Thread类的方法? 2019-04-28
从100万个数中找出最大的前100个数-最小堆、分块 2019-04-28
并发下的ArrayList、HashMap 2019-04-28
仿牛客社区项目2.2登录模块——开发注册功能 2019-04-28
仿牛客社区项目2.3登录模块——会话管理Cookie、Session 2019-04-28
仿牛客社区项目2.4登录模块——生成验证码 2019-04-28
JDK-JRE-JVM关系、Java语言跨平台 2019-04-28
仿牛客社区项目2.5登录模块———登录退出功能 2019-04-28
仿牛客社区项目2.6登录模块———显示登录信息(拦截器、ThreadLocal) 2019-04-28
仿牛客社区项目2.8登录模块——检查登录状态(自定义注解、拦截器) 2019-04-28
仿牛客社区项目2.7登录模块——账号设置(上传图片、响应图片) 2019-04-28