mysql LOCK TABLES语句的超时是什么时候?
无法在任何地方找到它。
我试图设置变量innodb_lock_wait_timeout ini my.cnf但似乎它与另一个(行级别)锁定而不是表锁定有关。
对LOCK TABLES没有任何影响。
我想为死锁的情况设置一些低超时值,因为如果某些操作会使LOCK表出现错误,它会挂起整个站点!
例如,在您的网站上完成购买时,这是愚蠢的。
答案 0 :(得分:2)
我的解决方法是创建一个专用的锁表,然后在该表中锁定一行。这具有仅锁定特别想要锁定的进程的优点。应用程序的其他部分可以继续访问表,即使它们在某些时候被更新过程触及。
设置的
CREATE TABLE `mutex` (
EMPTY ENUM('') NOT NULL,
PRIMARY KEY (EMPTY)
);
用法的
set innodb_lock_wait_timeout = 1;
start transaction;
insert into `mutex` values();
[... do the real work here ... or somewhere else ... even a different machine ...]
delete from `mutex`;
commit;
答案 1 :(得分:1)
您为什么使用LOCK TABLES
?
如果您使用的是MyISAM(有时需要LOCK TABLES
),您应该转换为InnoDB。
如果您使用的是InnoDB,则不应使用LOCK TABLES
。相反,取决于innodb_lock_wait_timeout
(默认是不合理的高50秒)。你应该检查错误。
InnoDB死锁被捕获并立即导致错误。某些非死锁可能会等待innodb_lock_wait_timeout。
修改强>
由于交易看起来像
BEGIN;
SELECT ...;
compute some stuff
UPDATE ... (using that stuff);
COMMIT;
您需要在FOR UPDATE
。
SELECT
答案 2 :(得分:0)
我想你的意思是说默认的超时值;它是50 Seconds
每MySQL Documentation
它说
innodb_lock_wait_timeout默认值50以秒为单位的超时时间 在放弃之前,InnoDB事务可能会等待行锁定。该 默认值为50秒
答案 3 :(得分:0)
我认为你是在MySQL 5.0.10中引入的table_lock_timout变量之后但随后是removed in 5.5。不幸的是,发行说明没有指定使用的替代方案,我猜测一般的态度是切换到使用InnoDB交易,正如@Rick James在他的回答中所述。
我认为删除变量是无益的。其他人可能会将此视为XY Problem的情况,我们正在尝试通过更改锁定表的超时时间来修复症状(死锁),而实际上我们应该通过切换到事务来解决根本原因。 我认为可能仍然存在表锁比使用事务更适合应用程序的情况,并且可能更容易理解,即使它们表现更差。
使用LOCK TABLES
的好处是,您可以在继续之前说明您查询所依赖的表。对于事务,锁会在最后可能的时刻被抓取,如果无法获取和超时,则需要检查此故障并在重新尝试所有内容之前回滚。在锁定表查询上有1秒的超时(最小值)更简单,并且在您成功之前继续重试以获取锁定,然后在解锁表之前继续执行查询。这种逻辑不存在死锁的风险。
我相信开发人员的态度总结为documetation的以下摘录:
...避免使用LOCK TABLES语句,因为它没有提供 任何额外的保护,但反而降低了并发性。
答案 4 :(得分:0)
正确答案是lock_wait_timeout
系统变量。
来自文档:
此变量指定尝试获取的超时(以秒为单位) 元数据锁。允许值范围为1到31536000(1 年)。默认值为31536000。
此超时适用于使用元数据锁的所有语句。这些 包括对表,视图,存储过程的DML和DDL操作, 和存储的函数,以及LOCK TABLES,FLUSH TABLES WITH READ LOCK和HANDLER声明。