Pergunta

I've read and tested row-level locks in MySQL's InnoDB but I still find it hard to actually say "I know how locks work in MySQL"!

Here's my test data:

mysql> select * from lockable;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
|  1 | A  | A  |
|  2 | A  | B  |
|  3 | A  | C  |
|  4 | B  | A  |
|  5 | B  | B  |
|  6 | B  | C  |
|  7 | C  | A  |
|  8 | C  | B  |
|  9 | C  | C  |
+----+----+----+
9 rows in set (0.00 sec)

In order to test the MySQL's behaviour regarding row-level locks, I opened two terminals and connected to MySQL. I'm going to name them mysql1> and mysql2>. Here's what I executed on first terminal:

mysql1> ROLLBACK;
mysql1> BEGIN;
mysql1> SELECT id, c1, c2 FROM lockable WHERE c1 = "A" FOR UPDATE;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
|  1 | A  | A  |
|  2 | A  | B  |
|  3 | A  | C  |
+----+----+----+
3 rows in set (0.00 sec)

Then on the second terminal:

mysql2> SELECT * FROM lockable WHERE c1 = "B" FOR UPDATE;

To my surprise the above query will be blocked by the first one! So I rolled back the first terminal and started over:

mysql1> ROLLBACK;
mysql1> BEGIN;
mysql1> SELECT id, c1, c2 FROM lockable LIMIT 3 FOR UPDATE;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
|  1 | A  | A  |
|  2 | A  | B  |
|  3 | A  | C  |
+----+----+----+
3 rows in set (0.00 sec)

Then on the second terminal:

mysql2> SELECT * FROM lockable WHERE LIMIT 6,1  FOR UPDATE;

Again the second terminal is blocked by the first one! Is there any scenario in which not all of records of a table are locked? If not why is this called "row-level locking"?

Foi útil?

Solução

The answer to my question is said in MySQL's manual:

A locking read, an UPDATE, or a DELETE generally set record locks on every index record that is scanned in the processing of the SQL statement.

So locks are applied to records that are swept during a traverse, not all of the records. If no index is found then a full sweep is done and all of the records are locked. So I needed to set an index on the column., even then if some record is read while getting to the target records, then they are also locked (even though they might not be finally selected).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top