Search code examples
phpmysqlinnodbdatabase-deadlocks

LOCK TABLES can cause deadlocks in InnoDB?


From MySQL manual ( https://dev.mysql.com/doc/refman/8.0/en/innodb-deadlocks.html ):

To reduce the possibility of deadlocks, use transactions rather than LOCK TABLES statements

How deadlocks are possible by using LOCK TABLES in InnoDB?

For example, if I write

SET autocommit=0;
LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE;
... do something with tables t1-t4 here ...
COMMIT;
UNLOCK TABLES;

do I really have to check errors like 1213 every time I execute this script?


Solution

  • If you make sure to lock all the tables you will read or write in one LOCK TABLES statement, you should be able to avoid deadlocks.

    The other good reason to avoid using LOCK TABLES if you can use transactions instead is to allow row-level locking. LOCK TABLES only locks at the table level, which means concurrent sessions can't touch any rows in the table, even if your session doesn't need to lock them.

    This is a disadvantage for software that needs to allow multiple sessions to access tables concurrently. You're forcing table-level locking, which will put a constraint on your software's throughput, because all sessions that access tables will queue up against each other, and be forced to execute serially.

    What do you mean by "use t2"? A READ lock? What if I'm using only WRITE locks like in my example.

    I think he means if you read from table t2. Since you have that table locked for WRITE, that includes blocking any readers of that table as well. No other session can read or write the table until you UNLOCK.

    I'm not concerned about performance. I have a situation where I want to make things as simple as possible and LOCK TABLES feels much more intuitive to me than using transactions with paranoid level error checking.

    You will eventually find a case where you want your software to have good performance. You'll have to become more comfortable using transactions.