在事务期间是否会在两个语句之间应用约束?

问题描述 投票:0回答:1

我有一个配置,thing可以有多个属性,property可以属于多个东西:

CREATE TABLE thing (
  id integer NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE property (
  id integer NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE thingproperty (
    thing integer NOT NULL,
    property integer NOT NULL
);

ALTER TABLE thingproperty
ADD CONSTRAINT tp_thing
FOREIGN KEY (thing) REFERENCES thing(id)
ON UPDATE CASCADE ON DELETE CASCADE;

ALTER TABLE thingproperty
ADD CONSTRAINT tp_property
FOREIGN KEY (property) REFERENCES property(id)
ON UPDATE CASCADE ON DELETE CASCADE;

我想确保property只有在属于至少一个thing时才能存在,为此我写了这个事务去除了东西(然后还有必要的属性),但我不知道它是否正确:

START TRANSACTION;
DELETE FROM thing ... ;
DELETE FROM property
WHERE id NOT IN (
  SELECT property
  FROM thingproperty
);
COMMIT TRANSACTION;

所以我基本上信任引擎,在DELETE FROM thing ...查询运行之后,它立即应用tp_thing约束并删除属于删除的thingpropertything的记录,然后执行DELETE FROM property ...

这是一种安全的方法吗?

sql postgresql many-to-many constraints cascading-deletes
1个回答
1
投票

默认情况下,在事务中的每个命令之后立即应用约束。您可以(在这种情况下,您不希望)更改此行为,将约束声明为可延迟。阅读有关the documentation.中可延迟约束的更多信息

DEFERRABLE

不可以

这可以控制是否可以延迟约束。在每个命令之后立即检查不可延迟的约束。 (......)

© www.soinside.com 2019 - 2024. All rights reserved.