我创建了一个虚拟表:
CREATE TABLE `lock_test` (
`name` varchar(32) NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB ;
我锁定它:
LOCK TABLE lock_test write;
然后我尝试再次锁定它(相同的查询)。第二个锁定请求显然只是挂在那里。
select * from INFORMATION_SCHEMA.INNODB_LOCKS;
select * from INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
两者都是空的(返回零结果) - 我本来期望它们被填充。我有PROCESS
权限(显示PROCESSLIST
显示锁定工作)。
对于这些表格,我是否有完全错误的结束?肯定安装了Information Schema插件和InnoDB引擎(通过运行SHOW PLUGINS进行检查;)。
由于
答案 0 :(得分:1)
有趣的是 - '问题'是我试图直接锁定表两次,这似乎没有填充该表。我将其更改为两个相互干扰的交易,并且按预期工作。
答案 1 :(得分:0)
你有autocommit = 1
吗?如果是的话,那就是原因。在不同的层上有两种类型的锁,一种在MySQL层,一种在存储引擎(InnoDB)层。
来自MySQL文档,Interaction of Table Locking and Transactions:
当你调用
LOCK TABLES
时,InnoDB内部拥有自己的表锁,而MySQL则拥有自己的表锁。 InnoDB在下次提交时释放其内部表锁,但是为了释放其表锁,MySQL必须调用UNLOCK TABLES
。您不应该autocommit = 1
,因为然后InnoDB会在调用LOCK TABLES
后立即释放其内部表锁,并且很容易发生死锁。如果autocommit = 1
,InnoDB根本不会获取内部表锁,以帮助旧应用程序避免不必要的死锁。
同时检查这部分文档(最后2段):Locks Set by Different SQL Statements in InnoDB:
LOCK TABLES
设置表锁,但它是设置这些锁的InnoDB层之上的更高的MySQL层。 如果innodb_table_locks = 1
(默认值)和autocommit = 0
,InnoDB知道表锁,InnoDB上面的MySQL层知道行级锁。