最近有个项目需要并发情况下读写 mysql,看了下面这两篇文章,对 InnoDB 的隔离和加锁机制有了一定的理解。 https://tech.meituan.com/innodb-lock.html http://hedengcheng.com/?p=771
个人理解,Mysql/Innodb 的 RR 模式,大多数情况下是不需要我们手动加锁的,但是某些情况下需要手动加锁的。
我这样理解对吗?如果对的话,哪种情况需要手动加锁啊?
求大神指点。
1
bestrenxs OP 自己顶一下!
|
2
tuzhenyu 2017-10-09 16:00:15 +08:00 1
Innodb 的 RR 模式通过 MVCC 和间隙锁解决了脏读,不可重复读,幻读问题,不需要手动加锁吧(同小白--)
|
8
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 |
10
picone 2017-11-06 17:15:29 +08:00
MySQL 事务默认隔离级别是 RR,会有幻读产生, 假如一个 SELECT 查询了用户的资金, 觉得够钱就 UPDATE 它。那么问题来了,如果在事务提交前另外一个 client 也 SELECT 了用户的资金,发现也够钱,也去 UPDATE 它,可能就变成负数了。
解决方法又俩: 1. 不太推荐而又简单的:串行化事务,也就是一个个查询去执行,不会有并发问题。 2. 使用锁,锁定要查询的那个用户,如#8 所说的。 但如果是做比较大的系统要注意一下死锁问题,假如有另外一个操作锁定另外一个数据,然后等待用户表的锁释放,而用户表的释放又等待刚才锁的释放, 大家互相等待,hhh。解决方法又是让他仅有一个线程获取到锁,不要同时获取到这两种锁。 |
11
ofblyt 2017-12-26 15:53:52 +08:00
@picone 我觉得你说的不对吧,幻读是针对 insert 来讲的,这两个 update 应该是属于可重复读级别的吧,理解有误请指正
|
14
picone 2017-12-26 16:19:25 +08:00
@ofblyt #13
幻读是指 在事物执行过程中,相同的两个查询语句得到的记录集不同。无论 insert 或者 update 都可能发生 https://en.wikipedia.org/wiki/Isolation_(database_systems) |