MySQL行级锁

来源:互联网 发布:qt编程软件 编辑:程序博客网 时间:2024/06/16 01:45

前言

如果在查询数据时,然后在同一个事务里插入或者修改相关的数据,常规的select语句不会提供足够的保护。其他的事务可以修改或者删除你正在查询的行。InnoDB支持两种可以提供安全机制的读取锁:

SELECT ... LOCK IN SHARE MODE 在读取的行上设置一个共享锁,其他的session可以读取这些行,但在你的事务提交之前不可以修改它们。如果这些行里有被其他的还没有提交的事务修改,你的查询会等到那个事务结束之后使用最新的值。

索引搜索遇到的记录,SELECT ... FOR UPDATE 会锁住行及任何关联的索引条目,和你对那些行执行update语句相同。其他的事务会被阻塞在对这些行执行update操作,获取共享锁,或从某些事务隔离级别读取数据等操作。一致性读会忽略在读取视图上的记录的任何锁。(旧版本的记录不能被锁定;它们通过应用撤销日志在记录的内存副本上时被重建。)

所有被共享锁和排他锁查询所设置的锁都会在事务提交或者回滚之后被释放。

使用SELECT FOR UPDATE 为update操作锁定行,只适用于autocommit被禁用(当使用START TRANSACTION开始事务或者设置autocommit为0时)。如果autocommit已启用,符合规范的行不会被锁定。


MySQL中的共享锁与排他锁

行级锁是MySQL中锁定粒度最细的一种锁,行级锁能大大减少数据库操作的冲突。行级锁分共享锁排他锁两种

共享锁(Share Lock ,S锁)

共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。如果事务T对数据D加上共享锁后,则其他事务只能对D再加共享锁,不能加排他锁。获准共享锁的事务只能读取数据,不能修改数据。

SELECT ... LOCK IN SHARE MODE;

在查询语句后面增加 LOCK IN SHARE MODE ,MySQL会对查询结果中的每行都加共享锁, 当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。

排他锁(eXclusive Lock ,X锁)

排他锁又称写锁,如果事务T对数据D加上排他锁后,则其他事务不能再对D加任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

SELECT ... FOR UPDATE;

在查询语句后面增加 FOR UPDATE,MySQL会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。
对于Insert、Update、Delete,InnoDB会自动给涉及的数据加排他锁(X锁);对于一般的Select语句,InnoDB不会加任何锁。