原文: 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. CMDB服务器管理系统【s5day88】:采集资产-文件配置(二)

    上节疑问: 1.老师我们已经写到global_settings里了,为什么还要写到__init__.py setting 这的作用是为了:整合起两个的组合global_settings和setting ...

  2. [JDK8]读写锁的改进:StampedLock

    StampedLock是Java8引入的一种新的锁机制,简单的理解,可以认为它是读写锁的一个改进版本,读写锁虽然分离了读和写的功能,使得读与读之间可以完全并发,但是读和写之间依然是冲突的,读锁会完全阻 ...

  3. springboot2 pagehelper 使用笔记

    作者:cnJun 博客专栏: https://www.cnblogs.com/cnJun/ pom.xml <parent> <groupId>org.springframew ...

  4. [物理学与PDEs]第2章习题9 粘性流体动能的衰减

    设 $\Omega\subset {\bf R}^3$ 为有界域, ${\bf u}$ 为 Navier-Stokes 方程组 (3. 4)-(3. 5) 满足边界条件 (3. 7) 的解, 其中体积 ...

  5. nnet3 TDNN chunk, left-context, right-context

    chunk-width 数据块的宽度 NnetIo name=="input" indexes,left-context+num-frame+right-context=5+7+6 ...

  6. Leetcode#70. Climbing Stairs(爬楼梯)

    题目描述 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: 2 解 ...

  7. 设计模式六: 模板方法(Template Method)

    简介 模板方法属于行为型模式的一种. 实现层面上, 在抽象类中定义了算法或流程的骨架, 将其中易变的部分延迟到子类实现, 也就是允许它的子类实现其中的某些步骤. 模板方法适用于算法不变, 但算法中某些 ...

  8. JQuery Advanced

    1.Jquery Utility <1> Type & Function & setTimeOut <!DOCTYPE html> <html lang= ...

  9. gitlab+PHP 自动部署设计方案

    2018-9-26 14:00:39 星期三 场景: 由于某种情况, 不能使用Jenkins, so......只有自己实现了 看图: webUI 设计方案, - 文件夹A, 用来存放git分支- 文 ...

  10. Linux -- Centos6 yum安装相关问题与处理

    Centos6 yum安装相关问题与处理 由于要使用yum下载文件,突然yum下载不了想要的文件,想更换yum源,结果得重新安装yum 来自本人GitHub地址https://github.com/m ...