trx1 select * from table where refId=4 for update
trx2 insert into table (refId) values (2); block
trx2 will be blocked, i knew trx1 will keep it gap lock, [1,4),[4,7);
my question is why keep gap lock? "insert val 2" is not conflict "select where refId=4 for update", why innodb will keep gap lock, why not use record-lock?
this question has been bothering me for a long time, please tech god save me.
InnoDB implements standard row-level locking where there are two types of locks, shared ( S ) locks and exclusive ( X ) locks. A shared ( S ) lock permits the transaction that holds the lock to read a row. An exclusive ( X ) lock permits the transaction that holds the lock to update or delete a row.
It is important to create good indexes so that your queries do not scan more rows than necessary. InnoDB sets specific types of locks as follows. SELECT ... FROM is a consistent read, reading a snapshot of the database and setting no locks unless the transaction isolation level is set to SERIALIZABLE .
Interesting question.
The gap lock is needed to avoid phantom rows.
MySQL works in REPEATABLE-READ isolation level by default. If you run several times select ... for update
in your transaction, it should always return same result.
Suppose you don't have gap lock and trx2 inserted another row with refId=4 (index is not unique).
Then following select in trx1 will return two rows:
MariaDB [test]> select * from t1 where refId=4 for update;
+----+------+
| id | refId|
+----+------+
| 2 | 4 |
| 4 | 4 |
+----+------+
2 rows in set (0.00 sec)
It is not the same result as first select.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With