背景:有一次定位问题发现,在同一个session连接中对MYSQL部分表加锁,导致其它未加锁的表不能访问。
用Spring管理MYSQL数据连接,在多线程访问数据库的情况下容易出问题。一个线程中对部分表加锁了,尚未释放。其它线程访问同一数据库中其它未加锁的表,也会访问失败。
测试了一把:
步骤一、使用Navicat连接MYSQL数据库。编写如下4句SQL。
LOCK TABLES tbl_A WRITE;
LOCK TABLES tbl_B WRITE;
DELETE FROM tbl_B;
UNLOCK TABLES;
步骤二、先执行1、再执行3。报如下错误:[Err] 1100 - Table ‘tbl_B’ was not locked with LOCK TABLES。
步骤三、先执行1、再执行2、再执行3。正常。
步骤四、选两台电脑用Navicat连同一个库。在一台电脑上执行1、在另一台电脑上执行3,可以正常执行。说明加锁升级控制在一个连接会话中,不同的连接不受影响。
结论:在共享数据库会话连接的多线程程序中对数据库表加锁,务必对所有要访问的表都加锁。不同会话连接则不受这类锁升级的影响。