[The MySQL] row-level locks SELECT ... LOCK IN SHARE MODE SELECT ... FOR UPDATE and

1. MR.

Translation from the official document: 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:

If you query the data, and then insert or modify the relevant data in the same transaction, the conventional select statement does not provide adequate protection. Other transactions can modify or delete a row you are querying. InnoDB supports two read lock can provide security mechanism:

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 is set on the line that reads a shared lock, other session can read these lines, but you can not modify them before the transaction commits. If these lines, there are other matters to be modified has not been submitted, your query will wait until after the end of the transaction using the latest value.

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

Record index search encountered an index entry SELECT ... FOR UPDATE locks the line and any associated, identical to those lines and you execute update statement. Other transactions will be blocked in the implementation of these lines update operations, acquire a shared lock, or read some data from the transaction isolation level and so on. Consistency read ( Consistent Nonlocking Reads ) ignores any lock on the record of the reading view. (The old version of the recording can not be locked; they are rebuilt by applying undo log is on the in-memory copy of the record.)

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.

All shared locks and exclusive locks set of query lock will be released after the transaction is committed or rolled back.

NOTE: 
using SELECT FOR UPDATE row lock for the update operation applies only to autocommit is disabled (when the start START TRANSACTION autocommit transaction or set to 0). If autocommit is enabled, compliant lines will not be locked.

Second, summary

Here Reference: shared locks in MySQL with exclusive lock

SELECT ... LOCK IN SHARE MODE: shared locks (S locks, share locks). Other transactions can read data but can not modify the data until all shared locks are released.

If the transaction after row of data plus a shared lock, can read and write; other transactions that data can be shared locks, but can not add exclusive lock, and can only read data, the data can not be modified.

SELECT ... FOR UPDATE: exclusive lock (X lock, exclusive locks). If the transaction after the data plus exclusive lock, other transactions can not add any of the data lock. Obtain an exclusive lock transaction not only read data, but also to modify the data.

Note: Ordinary default select statement is not locked, but the default CUD operations plus exclusive lock.

Third, verify

Note: Use mysql version 5.8.9, InnoDB transaction isolation level is the default isolation level repeatable read (Repeated Read).

Verify the following situations:

  1. After the current transaction acquires a shared lock, you can read and write, whether other transactions can read and write and acquire a shared lock;
  2. After the two transactions acquire shared locks, can you update operations;
  3. After the current transaction acquires an exclusive lock, other transactions if you can read and write and acquire a shared lock;
  4. Whether the data can be added to a more exclusive lock;
  5. Relations row locks and indexes;
  6. Index data repetition rate is too high will result in a full table scan;

1, after the current transaction acquires a shared lock, can read and write, whether other transactions can read and write and acquire a shared lock: you can read, you can acquire a shared lock, can not write

The current transaction can write: 
Write pictures described here

1 transaction after obtaining a row of data shared locks, transaction 2 updates the row blocking: 
Write pictures described here

After the transaction submitted 1, 2 transaction was successful: 
Write pictures described here

2, two transactions while sharing a row of data after acquiring lock, can perform an update operation: not

Two transactions simultaneously acquire data in a row shared locks, transaction 1 updates the row blocking: 
Write pictures described here

After submitting the transaction 2, 1 transaction was successful: 
Write pictures described here

3, the current transaction to obtain data in a row exclusive lock, other transactions if you can read and write and acquire a shared lock on the data line: other transactions can be read, can not acquire a shared lock, can not write

可以读该行数据: 
Write pictures described here

不可以获取该行数据共享锁: 
Write pictures described here

不可以更新该行数据: 
Write pictures described here

4、是否可对一条数据加多个排他锁:不可以 
Write pictures described here

5、行锁和索引的关系:查询字段未加索引(主键索引、普通索引等)时,使用表锁

注:InnoDB行级锁基于索引实现。

未加索引时,两种行锁情况为(使用表锁): 
- 事务1获取某行数据共享锁,其他事务可以获取不同行数据的共享锁,不可以获取不同行数据的排他锁 
- 事务1获取某行数据排他锁,其他事务不可以获取不同行数据的共享锁、排他锁

加索引后,两种行锁为(使用行锁):

  • 事务1获取某行数据共享锁,其他事务可以获取不同行数据的排他锁
  • 事务1获取某行数据排他锁,其他事务可以获取不同行数据的共享锁、排他锁

未加索引表结构: 
Write pictures described here

未加索引,事务1获取某行数据共享锁,事务2获取不同行数据共享锁成功: 
Write pictures described here

未加索引,事务1获取某行数据共享锁,事务2更新不同行数据阻塞: 
Write pictures described here

未加索引,事务1获取某行数据排他锁,事务2获取不同行数据共享锁阻塞: 
Write pictures described here

未加索引,事务1获取某行数据排他锁,事务2获取不同行数据排他锁阻塞: 
Write pictures described here

加索引后表结构: 
Write pictures described here

加索引后,事务1获取某行数据共享锁,事务2更新不同行数据成功: 
Write pictures described here

加索引后,事务1获取某行数据排他锁,事务2获取不同行数据共享锁成功: 
Write pictures described here

加索引后,事务1获取某行数据排他锁,事务2获取不同行数据排他锁成功: 
Write pictures described here

6、索引数据重复率太高会导致全表扫描:当表中索引字段数据重复率太高,则MySQL可能会忽略索引,进行全表扫描,此时使用表锁。可使用 force index 强制使用索引。

表结构:

CREATE TABLE `room` (
  `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL, `username` varchar(200) NOT NULL DEFAULT '', `state` varchar(255) NOT NULL DEFAULT '-1', `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `index_uid` (`uid`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

表数据: 
Write pictures described here

获取 uid = ‘11’ 的数据的行锁并更新,但更新失败: 
Write pictures described here

降低数据重复率,更新成功: 
Write pictures described here

Write pictures described here

强制使用索引,更新成功:force index(index_uid) 
Write pictures described here

Note: If you use table locks here, why other transactions can acquire an exclusive lock?

A: Because the use of  force index , and  InnoDB row-level locking based on the index to achieve , so here are using a row lock.

Four, InnoDB row lock type Introduction

Reference: Mysql InnoDB those in the lock mechanism

Three types of InnoDB row lock:

    • Record Lock: lock on an index entry, locking qualified rows. Other transactions can not modify, and delete lock entries;
    • Gap Lock: on the "gap" between the index entry lock, the lock range of records, the index does not include the items themselves. Inserting data within the range of other transactions can not be locked;
    • Next-key Lock: Lock index entry itself and the index range, namely Record combination of Gap Lock and Lock. Magic solve reading problems.

Guess you like

Origin www.cnblogs.com/zping/p/10955750.html