在具有并发事务的级联DELETE之后INSERT

时间:2017-03-08 20:12:47

标签: sql postgresql

假设我有两个表:

CREATE TABLE t1 (
  id VARCHAR
  PRIMARY KEY (id)
)

CREATE TABLE t2 (
  id VARCHAR
  t1_id VARCHAR
  PRIMARY KEY (id)
  FOREIGN KEY (t1_id) REFERENCES t1 (id) ON DELETE CASCADE
)

现在假设我运行了以下事务,其中一个单独的事务在删除后正好运行:

BEGIN;
DELETE FROM t1 where id = 'id';
  -- other transaction, INSERT INTO t2 (id, t1_id) VALUES ('other2', 'id'); --
INSERT INTO t1 (id) VALUES ('id');
INSERT INTO t2 (id, t1_id) VALUES ('other', 'id');
COMMIT;

其他交易会失败吗?我对docs的理解是,它会等待第一个DELETE完成。

如果我希望第二个事务等待以下INSERTS完成,我是否需要显式锁定?

2 个答案:

答案 0 :(得分:2)

我刚刚在postgres 9.5中对此进行了测试,它就像你描述的那样工作。包括它使用显式锁:

BEGIN;
LOCK t1;
DELETE FROM t1 where id = 'id';
  -- other transaction, INSERT INTO t2 (id, t1_id) VALUES ('other2', 'id'); --
INSERT INTO t1 (id) VALUES ('id');
INSERT INTO t2 (id, t1_id) VALUES ('other', 'id');
COMMIT;

另一个事务现在成功完成。

答案 1 :(得分:1)

如果只有一个用户运行代码,那么您的查询是正确的。它运行在上下,你不需要任何锁。但是如果多个用户可以运行它,你可以锁定t1,删除并插入然后释放锁。