[Tutorial] MySQL table lock


In this tutorial, you will learn how to use MySQL locks to coordinate table access between sessions.

MySQL allows client sessions to explicitly acquire table locks to prevent other sessions from accessing the table during a specific period of time. Client sessions can only acquire or release table locks for themselves. It cannot acquire or release table locks for other sessions.

Before the detailed introduction, we will create a sample database named sampledb, which contains a simple tbl table to simulate the practice table locking statement.

CREATE DATABASE IF NOT EXISTS testdb;    USE testdb;  CREATE TABLE tbl (    id int(11) NOT NULL AUTO_INCREMENT,    col int(11) NOT NULL,    PRIMARY KEY (id)  ); 

LOCK and UNLOCK tables syntax

The simple form of acquiring a table lock is as follows:

LOCK TABLES table_name [READ | WRITE] 

You can put the name of the table after the LOCK TABLES keyword, followed by a lock type. MySQL provides two lock types: READ and WRITE. We will introduce these two lock types in detail in the next section.

To release the lock of the table, use the following statement:

UNLOCK TABLES; 

Table locked as READ

The READ lock of the table has the following functions:

At the same time, the READ lock of the table can be acquired through multiple sessions. In addition, other sessions can read data from the table without acquiring a lock.

A session holding a READ lock can only read data from the table, but cannot write. In addition, other sessions cannot write data to the table before releasing the READ lock. A write operation from another session will be put into a wait state until the READ lock is released.

If the session terminates normally or abnormally, MySQL will implicitly release all locks. This is also related to WRITE locks.

Let's take a look at how the READ lock works in the following situations.

First, connect to the testdb database. To find the current connection ID, use the CONNECTION_ID() function, as shown below:

mysql> SELECT CONNECTION_ID();  +-----------------+  | CONNECTION_ID() |  +-----------------+  |              6 |  +-----------------+  1 row in set 

Then, insert one into the tbl table.

INSERT INTO tbl(col) VALUES(10); 

Next, retrieve all rows from the above table tbl.

mysql> SELECT * FROM tbl;  +----+-----+  | id | col |  +----+-----+  |  1 |  10 |  +----+-----+  1 row in set 

After that, to acquire the lock, you can use the LOCK TABLE statement. Finally, in the same session, if you try to insert a new row in the tbl table, you will receive an error message.

mysql> LOCK TABLE tbl READ;  Query OK, 0 rows affected    mysql> INSERT INTO tbl(col) VALUES(11);  1099 - Table 'tbl' was locked with a READ lock and can't be updated  mysql> 

So once the READ lock is obtained, data cannot be written to the table in the same session. Let's look at the READ lock from different sessions.

First, open another terminal and connect to the database testdb, and then check the connection ID:

mysql> SELECT CONNECTION_ID();  +-----------------+  | CONNECTION_ID() |  +-----------------+  |              7 |  +-----------------+  1 row in set 

Then, retrieve the data from tbl as shown below –

mysql> SELECT * FROM tbl;  +----+-----+  | id | col |  +----+-----+  |  1 |  10 |  +----+-----+  1 row in set 

Next, insert a new row from the second session (session ID 7) into the tbl table.

MySQL table lock

The insert operation of the second session is in a waiting state because the first session has acquired a READ lock on the tbl table and has not yet released it.

You can use the SHOW PROCESSLIST statement to view detailed information, as shown below –

mysql> SHOW PROCESSLIST;  +----+------+-----------------+----------+---------+------+---------------------------------+---------------------------------+  | Id | User | Host            | db      | Command | Time | State                          | Info                            |  +----+------+-----------------+----------+---------+------+---------------------------------+---------------------------------+  |  2 | root | localhost:51998 | NULL    | Sleep  |  474 |                                | NULL                            |  |  3 | root | localhost:51999 | yiibaidb | Sleep  | 3633 |                                | NULL                            |  |  6 | root | localhost:52232 | testdb  | Query  |    0 | starting                        | SHOW PROCESSLIST                |  |  7 | root | localhost:53642 | testdb  | Query  |  110 | Waiting for table metadata lock | INSERT INTO tbl(col) VALUES(20) |  +----+------+-----------------+----------+---------+------+---------------------------------+---------------------------------+  4 rows in set 

After that, return to the first session and use the UNLOCK TABLES statement to release the lock. After releasing the READ lock from the first session, perform the INSERT operation in the second session.

Finally, check the data in the tbl table to see if the INSERT operation in the second session is actually executed.

mysql> SELECT * FROM tbl;  +----+-----+  | id | col |  +----+-----+  |  1 |  10 |  |  2 |  20 |  +----+-----+  2 rows in set 

WRITE the MySQL table lock

Table lock for WRITE has the following functions:

Only the session that owns the table lock can read and write data from the table.

Before releasing the WRITE lock, other sessions cannot read or write from the table.

Learn more about the working principle of WRITE locks.

First, acquire a WRITE lock from the first session.

LOCK TABLE tbl WRITE; 

Then, insert a new row in the tbl table.

INSERT INTO tbl(col) VALUES(11); 

No problem, the above statement may be executed normally. Next, read the data from the tbl table.

mysql> SELECT * FROM tbl;  +----+-----+  | id | col |  +----+-----+  |  1 |  10 |  |  2 |  20 |  |  3 |  11 |  +----+-----+  3 rows in set 

After that, open a second session connected to MySQL and try to write and read data:

MySQL puts these operations in a waiting state. You can use the SHOW PROCESSLIST statement to view it in the first session.

mysql> SHOW PROCESSLIST;  +----+------+-----------------+----------+---------+-------+---------------------------------+---------------------------------+  | Id | User | Host            | db      | Command | Time  | State                          | Info                            |  +----+------+-----------------+----------+---------+-------+---------------------------------+---------------------------------+  |  2 | root | localhost:51998 | NULL    | Sleep  |  8477 |                                | NULL                            |  |  3 | root | localhost:51999 | yiibaidb | Sleep  | 11636 |                                | NULL                            |  |  8 | root | localhost:54012 | testdb  | Sleep  |  119 |                                | NULL                            |  |  9 | root | localhost:54013 | testdb  | Query  |    0 | starting                        | SHOW PROCESSLIST                |  | 10 | root | localhost:54016 | testdb  | Query  |    49 | Waiting for table metadata lock | INSERT INTO tbl(col) VALUES(21) |  +----+------+-----------------+----------+---------+-------+---------------------------------+---------------------------------+  5 rows in set 

Finally, release the lock from the first session. Execute the following statement –

UNLOCK TABLES; 

After executing the above statement, you will see all pending operations in the second session have been executed.

SELECT * FROM tbl;  Query OK, 1 row affected    +----+-----+  | id | col |  +----+-----+  |  1 |  10 |  |  2 |  20 |  |  3 |  11 |  |  4 |  21 |  +----+-----+  4 rows in set 

In this tutorial, we have shown you how to lock and unlock: READ and WRITE operations in order to coordinate table access between sessions


 

Guess you like

Origin blog.csdn.net/weixin_45713725/article/details/114581117