原文: http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

In some circumstances, a consistent (nonlocking) read is not convenient and a locking read is required instead. InnoDB supports two types of locking reads:

  • 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.

  • For index records the search encounters, SELECT ... FOR UPDATE blocks other sessions from doing SELECT ... LOCK IN SHARE MODE or from reading in certain transaction isolation levels. Consistent reads will ignore any locks set on the records that exist in the read view. (Old versions of a record cannot be locked; they will be reconstructed by applying undo logs on an in-memory copy of the record.)

These clauses are primarily useful when dealing with tree-structured or graph-structured data, either in a single table or split across multiple tables.

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

As an example of a situation in which a locking read is useful, suppose that you want to insert a new row into a table child, and make sure that the child row has a parent row in table parent. The following discussion describes how to implement referential integrity in application code.

Suppose that you use a consistent read to read the table parent and indeed see the parent row of the to-be-inserted child row in the table. Can you safely insert the child row to table child? No, because it is possible for some other session to delete the parent row from the table parent in the meantime without you being aware of it.

The solution is to perform the SELECT in a locking mode using LOCK IN SHARE MODE:

SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;

A read performed with LOCK IN SHARE MODE reads the latest available data and sets a shared mode lock on the rows read. A shared mode lock prevents others from updating or deleting the row read. Also, if the latest data belongs to a yet uncommitted transaction of another session, we wait until that transaction ends. After we see that the LOCK IN SHARE MODE query returns the parent 'Jones', we can safely add the child record to the child table and commit our transaction.

Let us look at another example: We have an integer counter field in a table child_codes that we use to assign a unique identifier to each child added to table child. It is not a good idea to use either consistent read or a shared mode read to read the present value of the counter because two users of the database may then see the same value for the counter, and a duplicate-key error occurs if two users attempt to add children with the same identifier to the table.

Here, LOCK IN SHARE MODE is not a good solution because if two users read the counter at the same time, at least one of them ends up in deadlock when it attempts to update the counter.

To implement reading and incrementing the counter, first perform a locking read of the counter using FOR UPDATE, and then increment the counter. For example:

SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;

A SELECT ... FOR UPDATE reads the latest available data, setting exclusive locks on each row it reads. Thus, it sets the same locks a searched SQL UPDATE would set on the rows.

The preceding description is merely an example of how SELECT ... FOR UPDATE works. In MySQL, the specific task of generating a unique identifier actually can be accomplished using only a single access to the table:

UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1);
SELECT LAST_INSERT_ID();

The SELECT statement merely retrieves the identifier information (specific to the current connection). It does not access any table.

转 MYSQL SELECT ... FOR UPDATE and SELECT ... LOCK IN SHARE MODE Locking Reads的更多相关文章

  1. 浅谈select for update 和select lock in share mode的区别

    有些情况下为了保证数据逻辑的一致性,需要对SELECT的操作加锁.InnoDB存储引擎对于SELECT语句支持两种一致性的锁定读(locking read)操作. . SELECT …… FOR UP ...

  2. SELECT ... FOR UPDATE or SELECT ... FOR SHARE Locking Reads session

    小结: 1.注意使用限制 Locking reads are only possible when autocommit is disabled (either by beginning transa ...

  3. select for update和select for update wait和select for update nowait的区别

    CREATE TABLE "TEST6" ( "ID" ), "NAME" ), "AGE" ,), "SEX ...

  4. mysql: SELECT ... FOR UPDATE 对SELECT语句的阻塞实验

    开两个连接A, B, 分别执行以下三个sql start 和 start ; 在A执行完1和2后, B执行1, 正常B执行2, 立即返回B执行3, 这时候被阻塞了 A执行3后, B的3立即返回 可以得 ...

  5. Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  6. mysql锁SELECT FOR UPDATE【转】

    MySQL 使用SELECT ... FOR UPDATE 做事务写入前的确认 以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEATABLE ...

  7. Select for update/lock in share mode 对事务并发性影响

    select for update/lock in share mode 对事务并发性影响 事务并发性理解 事务并发性,粗略的理解就是单位时间内能够执行的事务数量,常见的单位是 TPS( transa ...

  8. MySQL 使用SELECT ... FOR UPDATE 做事务写入前的确认(转)

    Select…For Update语句的语法与select语句相同,只是在select语句的后面加FOR UPDATE [NOWAIT]子句. 该语句用来锁定特定的行(如果有where子句,就是满足w ...

  9. mysql SELECT FOR UPDATE语句使用示例

    以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEATABLE READ,在SELECT 的读取锁定主要分为两种方式:SELECT ... LO ...

随机推荐

  1. C#开发Windows服务详细流程

    1.Windows服务简单介绍 Windows服务程序是在Windows操作系统下能完成特定功能的可执行的应用程序,主要用于长时间运行的功能或者执行定时任务.一般情况下,用户不能通过用户界面来安装和启 ...

  2. [Android] Android 实现类似 今日头条 视频播放列表

    演示实例如下: Talk is cheap. Show me the code 话不多说,代码在这里下载! https://github.com/wukong1688/Android_BaseVide ...

  3. js 数字前自动补零

    num为传入的数字,n为需要的字符长度 return (Array(n).join(0) + num).slice(-n); 例如 我想返回两位数  输入6 然后返回06 就可以这样写: return ...

  4. svn 支持中文显示

    https://blog.csdn.net/chentengkui/article/details/77543498 https://blog.csdn.net/bugall/article/deta ...

  5. 关于MySQL中的8个 character_set 变量

    https://blog.csdn.net/sun8112133/article/details/79921734 本篇会简单介绍在 MySQL 中关于 8个 character_set 变量的基本作 ...

  6. 查不到opencv版本的问题

    检查opencv版本:pkg-config --modversion opencv 前两天卸载了opencv3.0,想重装2.4版本.安装是没有问题,但现在查不到opencv版本,程序也编译不通过. ...

  7. 【溯源分析】疑似"摩诃草"组织最新样本分析及域名资产揭露

    1)场景 摩诃草组织(APT-C-09),又称HangOver.Patchwork.Dropping Elephant以及白象.该组织归属南亚某国,主要针对中国.巴基斯坦等亚洲国家和地区进行网络间谍活 ...

  8. JMeter学习笔记02-基础介绍

    基本构成 1)负载发生器:产生负载,多线程模拟用户行为 2)用户运行期:脚本运行引擎,用户运行器附加在线程上,根据指定脚本模拟指定的用户行为 3)资源发生器:生成测试过程中服务器.负载机的资源数据 4 ...

  9. $(document).ready()和onload() html渲染时的区别

    不谈调用次数,加载先后问题,只看渲染时区别 1.都在数据绑定完加载. 2.ready可以有多个,且都执行,onload虽可以写多个,但是只执行最后一个. 3. $.ready = function ( ...

  10. org.hibernate.boot.MappingNotFoundException: Mapping (RESOURCE) not found :

    可能原因: hibernate映射文件hibernate.cfg.xml中mapping中resource写错了文件名或者路径