未加星标

MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE

字体大小 | |
[数据库(综合) 所属分类 数据库(综合) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏
一、译文

翻译来自官方文档:Locking Reads

If you query data and then insert or update related data within the same transaction, the regular SELECT statement does not give enough protection. Other transactions can update or delete the same rows you just queried. InnoDB supports two types of locking reads that offer extra safety:

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

SELECT … LOCK IN SHARE MODE sets a shared mode lock on any rows that are read. Other sessions can read the rows, but cannot modify them until your transaction commits. If any of these rows were changed by another transaction that has not yet committed, your query waits until that transaction ends and then uses the latest values.

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

For index records the search encounters, SELECT … FOR UPDATE locks the rows and any associated index entries, the same as if you issued an UPDATE statement for those rows. Other transactions are blocked from updating those rows, from doing SELECT … LOCK IN SHARE MODE, or from reading the data in certain transaction isolation levels. Consistent reads ignore any locks set on the records that exist in the read view. (Old versions of a record cannot be locked; they are reconstructed by applying undo logs on an in-memory copy of the record.)

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

All locks set by LOCK IN SHARE MODE and FOR UPDATE queries are released when the transaction is committed or rolled back.

Note
Locking of rows for update using SELECT FOR UPDATE only applies when autocommit is disabled (either by beginning transaction with START TRANSACTION or by setting autocommit to 0. If autocommit is enabled, the rows matching the specification are not locked.

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

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

此处参考:mysql中的共享锁与排他锁

SELECT … LOCK IN SHARE MODE :共享锁(S锁, share locks)。其他事务可以读取数据,但不能对该数据进行修改,直到所有的共享锁被释放。

如果事务对某行数据加上共享锁之后,可进行读写操作;其他事务可以对该数据加共享锁,但不能加排他锁,且只能读数据,不能修改数据。

SELECT … FOR UPDATE:排他锁(X锁, exclusive locks)。如果事务对数据加上排他锁之后,则其他事务不能对该数据加任何的锁。获取排他锁的事务既能读取数据,也能修改数据。

注:普通 select 语句默认不加锁,而CUD操作默认加排他锁。

三、验证

对以下几种情况进行验证:

当前事务获取共享锁后,可以读写,其他事务是否可以进行读写操作和获取共享锁;两个事务同时获取共享锁后,是否可以进行update操作;当前事务获取排他锁后,其他事务是否可以进行读写操作和获取共享锁;是否可对一条数据加多个排他锁;行锁和索引的关系;

1、当前事务获取共享锁后,可以读写,其他事务是否可以进行读写操作和获取共享锁:可以读,可以获取共享锁,不可以写

当前事务可以写:
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE
事务1获取某行数据共享锁后,事务2更新该行阻塞:
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE
事务1提交之后,事务2更新成功:
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE

2、两个事务同时获取某行数据共享锁后,是否可以进行update操作:不可以

两个事务同时获取某行数据共享锁,事务1更新该行阻塞:
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE
事务2提交之后,事务1更新成功:
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE

3、当前事务获取某行数据排他锁后,其他事务是否可以对该行数据进行读写操作和获取共享锁:其他事务可以读,不可以获取共享锁,不可以写

可以读该行数据:
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE
不可以获取该行数据共享锁:
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE
不可以更新该行数据:
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE
4、是否可对一条数据加多个排他锁:不可以
MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE

5、行锁和索引的关系:未加索引时,使用表锁

本文数据库(综合)相关术语:系统安全软件

主题: SQLMySQL数据InnoDBTICTICU删除
分页:12
转载请注明
本文标题:MySQL行级锁SELECT...LOCKINSHAREMODE和SELECT...FORUPDATE
本站链接:http://www.codesec.net/view/481533.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 数据库(综合) | 评论(0) | 阅读(50)