ses*_*ses 5 postgresql transactions jdbc jdbi postgresql-9.4
PostgreSQL 数据库:v 9.4.24
\n\ncreate table my_a_b_data ... // with a_uuid, b_uuid, and c columns\nRun Code Online (Sandbox Code Playgroud)\n\n注意:my_a_b_data 保留对 a 和 b 表的引用。所以它保留了a和b的uuid。
\n\n其中:primary key (a_uuid, b_uuid)
还有一个索引:
\n\ncreate unique index my_a_b_data_pkey\n on my_a_b_data (a_uuid, b_uuid);\nRun Code Online (Sandbox Code Playgroud)\n\n在类似于 Java jdbc 的代码中,在一个事务范围内(start() -> [code (delete, insert)] ->commit()]):( org.postgresql:postgresql:42.2.5 driver)
delete from my_a_b_data where b_uuid = \'bbb\';\ninsert into my_a_b_data (a_uuid, b_uuid, c) values (\'aaa\', \'bbb\', null);\nRun Code Online (Sandbox Code Playgroud)\n\n发现插入失败,因为删除还没有删除。所以它失败了,因为它无法复制。
\n\n问: DB 不能在一个事务中执行删除和插入操作,这是否是PostgreSQL中的某种限制,因为 PostgreSQL 在执行删除提交之前不会更新其索引,因此插入会失败,因为 id 或 key(无论我们使用什么)已经存在于索引中?
\n\n可能的解决方案是什么?分成两笔交易?
\n\n更新:顺序完全相同。当我在SQL控制台中单独测试sql时。效果很好。我们使用 JDBI 库 v 5.29。
\n\n它看起来像这样:
\n\n @Transaction\n @SqlUpdate("insert into my_a_b_data (...; // similar for the delete\n public abstract void addB() ..\nRun Code Online (Sandbox Code Playgroud)\n\n所以在代码中:
\n\nthis.begin();\nthis.deleteByB(b_id);\nthis.addB(a_id, b_id);\nthis.commit();\nRun Code Online (Sandbox Code Playgroud)\n
小智 1
我在插入重复值时遇到了类似的问题,我通过使用插入和更新而不是删除来解决它。我在 Python 上创建了这个过程,但你也许能够重现它:
首先,您创建一个类似于要插入值的目标表的临时表,不同之处在于该表在提交后被删除。
CREATE TEMP TABLE temp_my_a_b_data
(LIKE public.my_a_b_data INCLUDING DEFAULTS)
ON COMMIT DROP;
Run Code Online (Sandbox Code Playgroud)我创建了一个 CSV(我必须合并不同的数据来输入),其中包含我想要在表中输入/插入的值,并使用 COPY 函数将它们插入到 temp_table ( temp_my_a_b_data )。
我在这篇文章中发现了与 Java 和 COPY PostgreSQL - \copy 命令相关的代码:
Run Code Online (Sandbox Code Playgroud)String query ="COPY tmp from 'E://load.csv' delimiter ','";
使用 INSERT INTO 但带有ON_CONFLICT子句,您可以决定在由于指定的约束而无法完成插入时执行操作,在下面的情况下我们进行更新:
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;`
Run Code Online (Sandbox Code Playgroud)注意事项:
我不确定,但您也许可以在不使用前面的步骤、临时表或副本的情况下执行第三步。您可以只循环遍历这些值:
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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3893 次 |
| 最近记录: |