【发布时间】:2020-05-08 21:18:05
【问题描述】:
PostgreSQL 数据库:v 9.4.24
create table my_a_b_data ... // with a_uuid, b_uuid, and c columns
注意:my_a_b_data 保留对 a 和 b 表的引用。所以它保留了a和b的uuid。
其中:primary key (a_uuid, b_uuid)
还有一个索引:
create unique index my_a_b_data_pkey
on my_a_b_data (a_uuid, b_uuid);
在Java 类似jdbc的代码中,在单一事务的作用域内:(start() -> [code (delete, insert)] ->commit()]) (org.postgresql:postgresql:42.2.5 driver)
delete from my_a_b_data where b_uuid = 'bbb';
insert into my_a_b_data (a_uuid, b_uuid, c) values ('aaa', 'bbb', null);
我发现插入失败,因为删除还没有删除。所以它失败了,因为它不能被复制。
问:在 PostgreSQL 中是否存在某种限制,DB 不能在一个事务中执行删除和插入操作,因为 PostgreSQL 不会更新其索引,直到执行删除的提交,因此插入将失败,因为索引中已经存在 id 或 key(我们可能使用的任何内容)?
有什么可能的解决方案?分成两笔交易?
更新:顺序完全相同。当我在 SQL 控制台中单独测试 sql 时。它工作正常。我们使用 JDBI 库 v 5.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声明中应该是b_uuid而不是b?如果不是,那么这种行为就不足为奇了。如果您的意思是b_uuid,那么如果两个语句都以该顺序运行在单个事务中,则不会发生这种情况。 -
b_uuid。是的。它是对 a 和 b 表的引用/id,它在此表中保留对 a 和 b 的引用。已更新。
-
列:a_uuid、b_uuid、c: - 值:aaa、bbb、null。 (我想已经修好了)。谢谢
-
这绝对不是 Postgres 造成的。除非您在两个不同的(并发)事务中运行这两个语句,否则这不会发生。我猜您的方法是同时调用的,因此您在程序中创建了两个不同的(并发)事务。您需要在单个事务中调用这两种方法
-
我不知道 JDBI,但您可能想检查它是否在单独的事务中运行带有
@Transaction注释的方法。考虑发布minimal reproducible example。
标签: postgresql jdbc transactions postgresql-9.4 jdbi