不懂就问:请问 Mysql/Innodb 的 RR 模式下哪种情况下需要手动加锁啊?

2017-10-09 14:57:10 +08:00
 bestrenxs

最近有个项目需要并发情况下读写 mysql,看了下面这两篇文章,对 InnoDB 的隔离和加锁机制有了一定的理解。 https://tech.meituan.com/innodb-lock.html http://hedengcheng.com/?p=771

个人理解,Mysql/Innodb 的 RR 模式,大多数情况下是不需要我们手动加锁的,但是某些情况下需要手动加锁的。

我这样理解对吗?如果对的话,哪种情况需要手动加锁啊?

求大神指点。

4924 次点击
所在节点    MySQL
16 条回复
bestrenxs
2017-10-09 15:32:20 +08:00
自己顶一下!
tuzhenyu
2017-10-09 16:00:15 +08:00
Innodb 的 RR 模式通过 MVCC 和间隙锁解决了脏读,不可重复读,幻读问题,不需要手动加锁吧(同小白--)
bestrenxs
2017-10-09 16:14:32 +08:00
@tuzhenyu 我又看了一遍文章,好像是你说的这样的。。谢谢
RubyJack
2017-10-09 16:50:44 +08:00
@tuzhenyu 别误人子弟啊,RR 哪里解决幻读了
bestrenxs
2017-10-09 17:01:39 +08:00
@RubyJack 看那两篇文章 InnoDB 是通过 GAP 锁解决了。。
RubyJack
2017-10-09 18:24:23 +08:00
@bestrenxs 你是对的,我没有看到前面的限定条件是 mysql
bestrenxs
2017-10-10 09:16:40 +08:00
@RubyJack 感谢回复
sunkuku
2017-10-24 10:56:03 +08:00
@bestrenxs innodb 内部实现了锁。有行锁(非空唯一索引),nextkey 锁(读写锁),意向锁。
如果你手动加锁,这种行为会导致他和事务相互影响。如果你在 innodb 中禁用了 AUTOCOMMIT,你可以手动释放锁。但是默认配置下,任何时候不要显式的获取锁。不管用什么引擎。

下面的 sql 语句都不符合 SQL 规范
- select .... lock in share mode
- select .... for update
- lock tables
bestrenxs
2017-10-24 12:41:51 +08:00
@sunkuku 好的 谢谢你
picone
2017-11-06 17:15:29 +08:00
MySQL 事务默认隔离级别是 RR,会有幻读产生, 假如一个 SELECT 查询了用户的资金, 觉得够钱就 UPDATE 它。那么问题来了,如果在事务提交前另外一个 client 也 SELECT 了用户的资金,发现也够钱,也去 UPDATE 它,可能就变成负数了。
解决方法又俩:
1. 不太推荐而又简单的:串行化事务,也就是一个个查询去执行,不会有并发问题。
2. 使用锁,锁定要查询的那个用户,如#8 所说的。
但如果是做比较大的系统要注意一下死锁问题,假如有另外一个操作锁定另外一个数据,然后等待用户表的锁释放,而用户表的释放又等待刚才锁的释放, 大家互相等待,hhh。解决方法又是让他仅有一个线程获取到锁,不要同时获取到这两种锁。
ofblyt
2017-12-26 15:53:52 +08:00
@picone 我觉得你说的不对吧,幻读是针对 insert 来讲的,这两个 update 应该是属于可重复读级别的吧,理解有误请指正
picone
2017-12-26 16:04:43 +08:00
@ofblyt #11 RR 全称 repeatable read, 可重复读。 所以这样解释有问题吗
ofblyt
2017-12-26 16:13:53 +08:00
@picone 但是你描述的是两个 update 的事务,应该和幻读没有关系吧,只有 insert 操作才会涉及到幻读
picone
2017-12-26 16:19:25 +08:00
@ofblyt #13
幻读是指 在事物执行过程中,相同的两个查询语句得到的记录集不同。无论 insert 或者 update 都可能发生
https://en.wikipedia.org/wiki/Isolation_(database_systems)
ofblyt
2017-12-26 16:24:13 +08:00
@picone A phantom read occurs when, in the course of a transaction, new rows are added by another transaction to the records being read,不知道你看没看你链接里面的内容……
picone
2017-12-26 17:50:54 +08:00
@ofblyt #15 嗯,你是对的, 他还有一个前提,需要 range-locks。感谢斧正

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/396171

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX