Mysql 进行试运行以查看数据库行是否已锁定

Mysql 进行试运行以查看数据库行是否已锁定,mysql,innodb,Mysql,Innodb,假设我试图在mysql Innodb中执行以下UPDATE语句: UPDATE main SET name = "Ralph" WHERE rowid=19283 在执行此语句之前,是否有办法在运行此更新之前查看rowid=19283上是否存在行/表级锁?或者是处理死锁的应用程序策略,以捕获异常,然后在事后处理它们?我发现,一旦出现死锁,如果没有一些非常循环的逻辑,通常不可能更新该行,因此我正在查看是否可以在潜在的update/INSERT语句出现之前检测到死锁 BEGIN; SELECT .

假设我试图在mysql Innodb中执行以下UPDATE语句:

UPDATE main SET name = "Ralph" WHERE rowid=19283
在执行此语句之前,是否有办法在运行此更新之前查看rowid=19283上是否存在行/表级锁?或者是处理死锁的应用程序策略,以捕获异常,然后在事后处理它们?我发现,一旦出现死锁,如果没有一些非常循环的逻辑,通常不可能更新该行,因此我正在查看是否可以在潜在的update/INSERT语句出现之前检测到死锁

BEGIN;
SELECT ... FOR UPDATE;  -- grab a lock on the row
... do some other processing, then eventually:
UPDATE ...   -- change the row (or maybe skip this in some cases)
COMMIT;
这允许多个连接优雅地更改该行,但不需要彼此踩在一起

不,这并不能消除死锁。它可能会将死锁转换为锁等待,这很好

而且这也不是一次完全的试运行。它将锁定从更新移回选择。如果在这项交易中发生了其他事情,而且是竞争性的交易,那么可能会出现僵局

如果有两个连接同时执行该事务,则其中一个将等待另一个完成。没有死锁。

常见的模式是

BEGIN;
SELECT ... FOR UPDATE;  -- grab a lock on the row
... do some other processing, then eventually:
UPDATE ...   -- change the row (or maybe skip this in some cases)
COMMIT;
这允许多个连接优雅地更改该行,但不需要彼此踩在一起

不,这并不能消除死锁。它可能会将死锁转换为锁等待,这很好

而且这也不是一次完全的试运行。它将锁定从更新移回选择。如果在这项交易中发生了其他事情,而且是竞争性的交易,那么可能会出现僵局


如果有两个连接同时执行该事务,则其中一个将等待另一个完成。没有死锁。

预先检查不会解决死锁。因此,捕获一个异常并在那里进行处理。如果您有两个事务更新相同的rowid=19283,那么应用程序的问题是尝试确定应该应用哪一个。我假设rowid是主键/唯一键。SHOW ENGINE INNODB STATUS可以显示最后一个死锁以进行调试。@danblack对此表示感谢-你的意思是在最新检测到的死锁部分下,还是还有其他部分可以提供信息?@danblack理论上,是的rowid是主键,但这似乎与FTS索引有关,这是非常奇怪的-记录锁定空间id 326第142679页n位320索引FTS_DOC_id_表的索引为什么会引起死锁需要更多信息抱歉。完整消息、查询、+SHOW CREATE TABLE{tablename}为主表。预先检查不会解决死锁。因此,捕获一个异常并在那里进行处理。如果您有两个事务更新相同的rowid=19283,那么应用程序的问题是尝试确定应该应用哪一个。我假设rowid是主键/唯一键。SHOW ENGINE INNODB STATUS可以显示最后一个死锁以进行调试。@danblack对此表示感谢-你的意思是在最新检测到的死锁部分下,还是还有其他部分可以提供信息?@danblack理论上,是的rowid是主键,但这似乎与FTS索引有关,这是非常奇怪的-记录锁定空间id 326第142679页n位320索引FTS_DOC_id_表的索引为什么会引起死锁需要更多信息抱歉。完整消息,查询,+显示主表的创建表{tablename}。