干 运行 查看数据库行是否被锁定
Do a dry run to see if a database row is locked or not
假设我正在尝试在 mysql (Innodb) 中执行以下 UPDATE
语句:
UPDATE main SET name = "Ralph" WHERE rowid=19283
有没有办法在执行此语句之前查看 运行 此更新之前是否在 rowid=19283 上有 row/table-level 锁?还是处理死锁的应用策略是捕捉异常,事后处理?我发现一旦达到死锁,如果没有一些非常循环的逻辑,通常不可能更新该行,所以我看看是否可以在潜在的 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;
这允许多个连接优雅地更改该行,但不会相互踩踏。
不,这并不能消除死锁。它可能将死锁变成"lock wait",这很好。
而且还不完全是 "dry run"。它将锁从 UPDATE
移回 SELECT
。如果在此过程中还有其他事情在发生,并且存在竞争事务,则可能会出现死锁。
如果您有 2 个连接在 "exactly" 同时执行该事务,一个将等待另一个完成。 (没有死锁。)
假设我正在尝试在 mysql (Innodb) 中执行以下 UPDATE
语句:
UPDATE main SET name = "Ralph" WHERE rowid=19283
有没有办法在执行此语句之前查看 运行 此更新之前是否在 rowid=19283 上有 row/table-level 锁?还是处理死锁的应用策略是捕捉异常,事后处理?我发现一旦达到死锁,如果没有一些非常循环的逻辑,通常不可能更新该行,所以我看看是否可以在潜在的 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;
这允许多个连接优雅地更改该行,但不会相互踩踏。
不,这并不能消除死锁。它可能将死锁变成"lock wait",这很好。
而且还不完全是 "dry run"。它将锁从 UPDATE
移回 SELECT
。如果在此过程中还有其他事情在发生,并且存在竞争事务,则可能会出现死锁。
如果您有 2 个连接在 "exactly" 同时执行该事务,一个将等待另一个完成。 (没有死锁。)