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

Will a constraint be applied between two statements during a transaction?

我有一个配置,一个 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 约束并删除 thingproperty 的记录属于DELETE FROM property ...执行前删除的thing(s)

这样做安全吗?

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

中阅读有关可延迟约束的更多信息

DEFERRABLE

NOT DEFERRABLE

This controls whether the constraint can be deferred. A constraint that is not deferrable will be checked immediately after every command. (...)