SELECT FOR UPDATE

MySQL uses SELECT ... FOR UPDATE for confirmation before transaction write

Taking MySQL's InnoDB as an example, the preset Tansaction isolation level is REPEATABLE READ, and the read lock in SELECT is mainly divided into two ways:

SELECT ... LOCK IN SHARE MODE SELECT ... FOR UPDATE

These two methods must wait for other transaction data to be submitted (Commit) before executing when SELECTing to the same data table during the transaction (Transaction). The main difference is that LOCK IN SHARE MODE can easily cause deadlock when one transaction wants to update the same form.

Simply put, if you want to UPDATE the same form after SELECT, it is better to use SELECT ... UPDATE.

For example: Suppose there is a quantity in the product form products that stores the number of products. Before the order is established, it must be determined whether the quantity of the product is sufficient (quantity>0), and then the quantity is updated to 1.

Unsafe practice:

SELECT quantity FROM products WHERE id=3; UPDATE products SET quantity = 1 WHERE id=3;

Why is it not safe?

A small number of cases may not be a problem, but a large amount of data access "definitely" will be a problem.

If we need to deduct inventory when quantity>0 It has become 0, but the program doesn't know it, and the wrong UPDATE goes on.

Therefore, the transaction mechanism must be used to ensure that the data read and submitted are correct.

So we can test it like this in MySQL: (Note 1)

SET AUTOCOMMIT=0; BEGIN WORK; SELECT quantity FROM products WHERE id=3 FOR UPDATE; ===========================================

At this time, the data with id=3 in the products data is locked (Note 3), and other transactions must wait for the transaction to be committed before they can be executed.

SELECT * FROM products WHERE id=3 FOR UPDATE (Note 2) This ensures that the numbers read by quantity in other transactions are correct. ===============================================

UPDATE products SET quantity = '1' WHERE id=3 ; COMMIT WORK;

===========================================

Commit is written to the database, and products are unlocked.

Note 1: BEGIN/COMMIT is the start and end point of the transaction. You can use two or more MySQL Command windows to interactively observe the lock status.

Note 2: During the transaction, only SELECT ... FOR UPDATE or LOCK IN SHARE MODE will wait for the end of other transactions before executing the same data. Generally, SELECT ... is not affected by this.

Note 3: Since InnoDB defaults to Row-level Lock, you can refer to this article for data column locking.

Note 4: Try not to use the LOCK TABLES command in InnoDB forms. If you have to use it, please read the official instructions for using LOCK TABLES in InnoDB to avoid frequent deadlocks in the system.


MySQL SELECT ... FOR UPDATE 的Row Lock 与Table Lock

The usage of SELECT ... FOR UPDATE has been introduced above, but it is necessary to pay attention to the data of the lock (Lock). Since InnoDB defaults to Row-Level Lock, MySQL will execute Row Lock (lock only the selected data) only if the primary key is "explicitly" specified, otherwise MySQL will execute Table Lock (lock the entire data table) ).

for example:

Suppose there is a form products, which has id and name two fields, id is the primary key.

Example 1: (Explicitly specify the primary key and have this data, row lock)

SELECT * FROM products WHERE id='3' FOR UPDATE;

Example 2: (Explicitly specify the primary key, if there is no such data, there is no lock)

SELECT * FROM products WHERE id='-1' FOR UPDATE;

Example 2: (no primary key, table lock)

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;

Example 3: (Primary key is ambiguous, table lock)

SELECT * FROM products WHERE id<>'3' FOR UPDATE;

Example 4: (Primary key is ambiguous, table lock)

SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

Note 1: FOR UPDATE only applies to InnoDB, and must be in a transaction block (BEGIN/COMMIT) to take effect.

Note 2: To test the locking status, you can use MySQL's Command Mode to open two windows for testing.

 

http://www.cnblogs.com/chenwenbiao/archive/2012/06/06/2537508.html

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326940697&siteId=291194637