MySQL“;“锁表”;暂停?

MySQL“;“锁表”;暂停?,mysql,transactions,locking,innodb,Mysql,Transactions,Locking,Innodb,mysql LOCK TABLES语句的超时是多少 到处都找不到 我试图在my.cnf中设置变量innodb_lock_wait_timeout,但它似乎与另一个(行级)锁定相关,而不是表锁定 简单地说,它对锁表没有影响 我想为死锁的情况设置一些较低的超时值,因为如果某些操作会锁定表,并且出现问题,则会挂断整个站点 例如,如果在你的网站上完成购买,这是愚蠢的。我想你的意思是说默认超时值;这是50秒 innodb_lock_wait_超时默认值为50秒 InnoDB事务可能会在放弃之前等待行锁定。

mysql LOCK TABLES语句的超时是多少

到处都找不到

我试图在my.cnf中设置变量innodb_lock_wait_timeout,但它似乎与另一个(行级)锁定相关,而不是表锁定

简单地说,它对锁表没有影响

我想为死锁的情况设置一些较低的超时值,因为如果某些操作会锁定表,并且出现问题,则会挂断整个站点


例如,如果在你的网站上完成购买,这是愚蠢的。

我想你的意思是说默认超时值;这是
50秒

innodb_lock_wait_超时默认值为50秒 InnoDB事务可能会在放弃之前等待行锁定。这个 默认值为50秒


为什么要使用
锁表

如果您使用的是MyISAM(有时需要
锁表
),则应转换为InnoDB

如果您使用的是InnoDB,则永远不要使用
锁表
。相反,依赖于
innodb\u lock\u wait\u timeout
(默认值为不合理的高达50秒)。你应该检查错误

InnoDB死锁被捕获并立即导致错误。某些非死锁可能会等待innodb_lock_wait_超时

编辑

因为交易看起来像

BEGIN;
SELECT ...;
compute some stuff
UPDATE ... (using that stuff);
COMMIT;
您需要在
的末尾添加
以进行更新
选择
,我想您需要的是MySQL 5.0.10中引入的变量,但随后又添加了该变量。不幸的是,发行说明没有指定可供使用的替代方案,我猜一般的态度是转向使用InnoDB事务,正如@Rick James在回答中所说的那样

我认为删除变量是没有帮助的。其他人可能会将此视为的情况,我们正试图通过更改锁定表的超时时间来修复症状(死锁),而实际上我们应该通过切换到事务来解决根本原因。我认为在某些情况下,表锁可能比使用事务更适合应用程序,并且可能更容易理解,即使它们的性能更差

使用
锁表
的好处在于,您可以在继续之前声明查询所依赖的表。对于事务,锁在最后可能的时刻被抓取,如果无法抓取并超时,则需要检查此故障并回滚,然后再次尝试所有操作。更简单的方法是在锁表查询上有一个1秒的超时(最小值),并不断尝试获取锁,直到成功,然后在解锁表之前继续查询。这种逻辑不存在死锁的风险

我相信开发商的态度可以从以下摘录中总结出来:

…避免使用LOCK TABLES语句,因为它不提供 任何额外的保护,但会降低并发性


我的工作是创建一个专用的锁表,并锁定该表中的一行。这样做的优点是只锁定特定要锁定的进程。应用程序的其他部分可以继续访问这些表,即使它们在某个时刻被更新过程所触及

设置

用法

正确答案是系统变量

从文件中:

此变量指定尝试获取的超时时间(秒) 元数据锁。允许值范围为1到31536000(1 年)。默认值为31536000

此超时适用于所有使用元数据锁的语句。这些 包括表、视图、存储过程上的DML和DDL操作, 和存储函数,以及锁表、带读取的刷新表 LOCK和HANDLER语句


我相信这是为行锁,而不是表锁。不,我的意思是,如何设置它。正如我所说,我试图改变你所说的价值观,但似乎没有效果。它可能与另一个锁定(例如选择…进行更新)相关,但这并不是我所需要的。在另一个事务完成之前,我需要让并发事务等待。但无论如何,谢谢你,似乎锁表没有任何超时,查询将一直挂起,直到锁被释放。是的,我也担心这一点。那太愚蠢了。。至于逻辑,表锁定正是我所需要的,但是我害怕死锁,所以我不得不离开这个解决方案。取而代之的是,我将使用我需要在锁中生成的唯一列(发票编号)进行INSERT IGNORE,如果它失败(例如,当同时有两个并发事务时),我将再次尝试生成发票编号。(这应该是可行的,但唯一的问题是,如果第一个事务将回滚,则发票编号将出现漏洞。(而在锁定表的情况下,这不可能发生,因为第二个并发事务将等待第一个事务的完成—无论完成是提交还是回滚)无论如何,谢谢你的回复。cheersi将锁表与innoDB事务一起使用,但这不是原因,原因是,我需要进行其他(理论上的)并发事务(或在一个特定表上选择)等待,直到第一个事务完成。除了使用锁定表之外,没有其他方法可以阻止对某个表的访问。假设我有表发票,需要生成自定义唯一id,然后在此表中插入行。因此,我需要在此表上进行选择,例如,year=2005,它将返回一些id,我将增加它并输入插入具有唯一发票id的新行,但理论上可以有两个并发线程同时执行select(year=2005)以构建“唯一”发票id或编号。因此,如果表被锁定,则其他并发线程无法处理该表
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;