MVCC非阻塞读取在某种程度上是没有锁定.即使编写者正在更新相同的行,MVCC也允许一个或多个读者获得对数据的可重复读取访问.在这种情况下不需要锁定.
例如,如果我更改某行,InnoDB会立即创建该行旧版本的副本.读取该数据的并发事务可以继续读取副本.只要您的交易持续,旧版本就会保留在数据库中.
如果您启动一个新事务,您将看到该行的最近提交的版本,旧版本最终可以被垃圾收集,这将回收一些空间.
锁定是指多个编写者尝试更新相同的行时.只有一个编写器一次可以更新一行,第一个更新行的编辑器将锁定它直到它们提交更改.其他作家必须等到第一个作家提交.但至少在行级锁定时,如果他们正在更新同一行,他们只会有争用.
来自@AlexYakunin的评论:
任意数量的并发线程都可以在同一行上获取共享锁.但是,独占锁需要不存在任何类型的锁 – 一次只有一个线程可以获得独占锁.
UPDATE总是请求独占锁,这是更常见的情况.在InnoDB中,共享锁用于一些更奇特的情况:
>我将具有外键的子行更新为父表.我在子行上获得X锁定,在父行上获得S锁定.基本上,当我更新依赖于父级的行时,没有人可以更新父行.
>我在阅读时明确使用SELECT … LOCK IN SHARE MODE来阻止对某些行的更新.这通常不是必需的.
>我执行任何SELECT,而我的事务隔离级别是SERIALIZABLE(这不常见).
>我发出导致重复键错误的INSERT,我的线程请求行上的共享锁.