Postgresql Postgres在单个事务中插入前删除
PostgreSQL数据库:V9.4.24Postgresql Postgres在单个事务中插入前删除,postgresql,jdbc,transactions,postgresql-9.4,jdbi,Postgresql,Jdbc,Transactions,Postgresql 9.4,Jdbi,PostgreSQL数据库:V9.4.24 create table my_a_b_data ... // with a_uuid, b_uuid, and c columns 注意:my_a_b_数据保留对a和b表的引用。所以它保留了a和b的UUID 其中:主键(a\u uuid,b\u uuid) 还有一个索引: create unique index my_a_b_data_pkey on my_a_b_data (a_uuid, b_uuid); 在Javajdbc-like
create table my_a_b_data ... // with a_uuid, b_uuid, and c columns
注意:my_a_b_数据保留对a和b表的引用。所以它保留了a和b的UUID
其中:主键(a\u uuid,b\u uuid)
还有一个索引:
create unique index my_a_b_data_pkey
on my_a_b_data (a_uuid, b_uuid);
在Javajdbc-like代码中,在作用域中有一个事务:(start()->[code(delete,insert)]->commit())
(org.postgresql:postgresql:42.2.5驱动程序
)
我发现插入失败,因为删除尚未删除。所以它失败了,因为它不能被复制
Q:PostgreSQL中是否存在某种限制,即DB不能在一个事务中执行删除和插入,因为PostgreSQL在执行删除提交之前不会更新其索引,因此插入将失败,因为索引中已经存在id或键(无论我们使用什么)
可能的解决办法是什么?分成两笔交易
更新:顺序完全相同。当我在sql控制台中单独测试sql时。它很好用。我们使用JDBI库V5.29
看起来是这样的:
@Transaction
@SqlUpdate("insert into my_a_b_data (...; // similar for the delete
public abstract void addB() ..
因此,在守则中:
this.begin();
this.deleteByB(b_id);
this.addB(a_id, b_id);
this.commit();
我在插入重复的值时遇到了类似的问题,我通过使用insert和Update而不是Delete解决了这个问题。我在Python上创建了这个过程,但您可能可以复制它:
CREATE TEMP TABLE temp_my_a_b_data
(LIKE public.my_a_b_data INCLUDING DEFAULTS)
ON COMMIT DROP;
INSERT INTO public.my_a_b_data
SELECT *
FROM temp_my_a_b_data
ON CONFLICT (a_uuid, b_uuid,c) DO UPDATE
SET a_uuid = EXCLUDED.a_uuid,
b_uuid = EXCLUDED. c = EXCLUDED.c;`
考虑事项: 我不确定,但您可能可以执行第三步,而无需使用前面的步骤、临时表或复制自。您可以只在值上循环:
INSERT INTO public.my_a_b_data VALUES(value1, value2, null)
ON CONFLICT (a_uuid, b_uuid,c) DO UPDATE
SET a_uuid = EXCLUDED.a_uuid,
b_uuid = EXCLUDED.b_uuid, c = EXCLUDED.c;
您的
insert
语句中应该是b_uid
而不是b
?如果不是,那么这种行为就不足为奇了。如果您的意思是b_uuid
,那么如果在单个事务中两条语句都按该顺序运行,则不会发生这种情况。对它是对a和b表的引用/id,它在该表中保留对a和b的引用。updated.columns:a_uuid,b_uuid,c:-值:aaa,bbb,null。(我想已经修好了)。这绝对不是由博士后引起的。除非您在两个不同(并发)事务中运行这两个语句,否则这是不可能发生的。我猜您的方法是并发调用的,因此您可以从程序中创建两个不同的(并发)事务。您需要在单个事务中调用这两个方法我不知道JDBI,但您可能希望检查它是否在单独的事务中运行带有@Transaction
注释的方法。考虑发布A。
INSERT INTO public.my_a_b_data
SELECT *
FROM temp_my_a_b_data
ON CONFLICT (a_uuid, b_uuid,c) DO UPDATE
SET a_uuid = EXCLUDED.a_uuid,
b_uuid = EXCLUDED. c = EXCLUDED.c;`
INSERT INTO public.my_a_b_data VALUES(value1, value2, null)
ON CONFLICT (a_uuid, b_uuid,c) DO UPDATE
SET a_uuid = EXCLUDED.a_uuid,
b_uuid = EXCLUDED.b_uuid, c = EXCLUDED.c;