背景:有一次定位问题发现,在同一个session连接中对MYSQL部分表加锁,导致其它未加锁的表不能访问。

用Spring管理MYSQL数据连接,在多线程访问数据库的情况下容易出问题。一个线程中对部分表加锁了,尚未释放。其它线程访问同一数据库中其它未加锁的表,也会访问失败。

测试了一把:

步骤一、使用Navicat连接MYSQL数据库。编写如下4句SQL。

  1. LOCK TABLES tbl_A WRITE;

  2. LOCK TABLES tbl_B WRITE;

  3. DELETE FROM tbl_B;

  4. UNLOCK TABLES;

步骤二、先执行1、再执行3。报如下错误:[Err] 1100 - Table ‘tbl_B’ was not locked with LOCK TABLES。

步骤三、先执行1、再执行2、再执行3。正常。

步骤四、选两台电脑用Navicat连同一个库。在一台电脑上执行1、在另一台电脑上执行3,可以正常执行。说明加锁升级控制在一个连接会话中,不同的连接不受影响。

结论:在共享数据库会话连接的多线程程序中对数据库表加锁,务必对所有要访问的表都加锁。不同会话连接则不受这类锁升级的影响。

05-11 13:04