读锁的概念和区别
如果在MySQL
的事务里查询数据,然后在同一事务中插入或更新相关数据,常规的SELECT
语句不能提供足够的保护。其他并行的事务可以更新或删除第一个事务里刚查询的相同行。 InnoDB
支持两种类型的读锁,提供了额外的安全性:
SELECT … LOCK IN SHARE MODE
在读取到的行上设置共享锁。其他会话可以读取行,也可以继续给行加共享锁,但是在当前事务提交之前其他会话不能修改加了共享锁的行。如果这些行中的任何一个被尚未提交的另一个事务更改,则当前查询将等待直到该事务结束,然后使用最新值。
SELECT … FOR UPDATE
用排他锁锁定行和任何关联的索引条目,就像在这些行上执行
UPDATE
语句一样。禁止其他事务在这些加了锁的行上进行UPDATE
、执行SELECT ... LOCK IN SHARE MODE
或者读取某些事务隔离级别的数据。
通过对比,发现FOR UPDATE
的加锁方式类似并发编程里的写锁,而LOCK IN SHARE MODE
则是读锁,同一时间点相同的行上只允许出现一个写锁,或者是多个读锁。一旦有一种锁在数据行上成功加上了锁,另外一种加锁尝试就会进入等待。