相关疑难解决方法(0)

SELECT ... FOR UPDATE是否应该包含ORDER BY?

假设我们执行......

SELECT * FROM MY_TABLE FOR UPDATE
Run Code Online (Sandbox Code Playgroud)

...... MY_TABLE中有多行.

理论上,如果两个并发事务执行此语句,但它恰好以不同的顺序遍历(并因此锁定)行,则可能发生死锁.例如:

  • 事务1:锁定行A.
  • 交易2:锁定B行.
  • 事务1:尝试锁定行B和块.
  • 事务2:尝试锁定行A和死锁.

解决此问题的方法是使用ORDER BY来确保始终以相同的顺序锁定行.

所以,我的问题是:这种理论上的僵局会在实践中发生吗?我知道有人工诱导它的方法,但它能否在正常运作中发生?我们应该只使用ORDER BY,还是省略它实际上是安全的?

我主要对Oracle和MySQL/InnoDB的行为感兴趣,但对其他DBMS的评论也会有所帮助.

---编辑---

以下是当锁定顺序不同时,如何在Oracle下重现死锁:

创建测试表并用一些测试数据填充它...

CREATE TABLE DEADLOCK_TEST (
    ID INT PRIMARY KEY,
    A INT 
);

INSERT INTO DEADLOCK_TEST SELECT LEVEL, 1 FROM DUAL CONNECT BY LEVEL <= 10000;

COMMIT;
Run Code Online (Sandbox Code Playgroud)

...从一个客户端会话(我使用SQL Developer),运行以下块:

DECLARE
    CURSOR CUR IS 
        SELECT * FROM DEADLOCK_TEST
        WHERE ID BETWEEN 1000 AND 2000 
        ORDER BY ID 
        FOR UPDATE;
BEGIN
    WHILE TRUE LOOP
        FOR LOCKED_ROW IN CUR …
Run Code Online (Sandbox Code Playgroud)

mysql oracle deadlock locking

15
推荐指数
1
解决办法
6096
查看次数

两个并发但相同的DELETE语句会导致死锁吗?

假设some_table有两行,主键12.以下语句序列可能导致死锁:

session 1: begin;
session 2: begin;
session 1: DELETE FROM my_table WHERE my_key = 1;
session 2: DELETE FROM my_table WHERE my_key = 2;
session 1: DELETE FROM my_table WHERE my_key = 2;
session 2: DELETE FROM my_table WHERE my_key = 1;
Run Code Online (Sandbox Code Playgroud)

如果两个会话以相同的顺序删除,则不会发生死锁.

现在,回答我的问题,如果DELETE语句触及多行会发生什么?例如:

session 1: begin;
session 2: begin;
session 1: DELETE FROM my_table;
session 2: DELETE FROM my_table;
Run Code Online (Sandbox Code Playgroud)

是否有可能两个并发但相同的DELETE语句将以不同的顺序删除行?是否可以强制执行删除顺序以避免死锁?

我在文档中找不到这些信息,所以我想说不能保证删除顺序(尽管它可能间接地作为实现细节).我想在这里仔细检查一下.

sql postgresql database-deadlocks postgresql-9.5

8
推荐指数
1
解决办法
351
查看次数