使用Npgsql的PostgreSQL主细节事务处理

时间:2017-08-24 08:40:43

标签: sql postgresql npgsql

假设我有这些表:

CREATE TABLE master 
master_id serial, 
master_desc character varying

CREATE TABLE details
details_masterrefid int,
details_desc character varying
CONSTRAINT master_detail_fkey(details_masterrefid)
REFERENCES master(master_id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION

然后我在C#中有一个代码,它基本上会首先将标头插入主表,然后遍历细节并将其插入到详细信息表中。

通过这样做,我必须首先插入主表,然后提交事务,如果成功,获取ID并使用它插入详细信息表。现在,问题是,如果细节出错并且插入不成功,我想回滚插入主表上的数据。但由于它已经承诺,我不能回滚。应该是全有或全无。主表和详细信息表。

我能想到的唯一解决方案是允许细节中的外键字段可以为空,然后如果一切都成功,则将外键字段更新为其各自的值。关于如何做得更好的任何建议?我不知道它是否是一种有效的解决方案。

1 个答案:

答案 0 :(得分:0)

您可以使用单一语句CTE

WITH ins1 AS (
  INSERT INTO master (cols...)
  VALUES (..)                            -- insert into master
  RETURNING master_id                    -- get generated id
)
INSERT INTO details (...)
SELECT master_id, ...                    -- insert into child table
FROM ins1;

<强> Rextester Demo

另一种方法是使用单个事务包装所有内容:

BEGIN TRAN

INSERT INTO master ...

INSERT INTO child ...

COMMIT;

这样你就会得到全有或全无的行为。