簡體   English   中英

Postgres 在單個事務中插入之前刪除

[英]Postgres delete before insert in single transaction

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);

我發現插入失敗了,因為刪除還沒有刪除。 所以它失敗了,因為它不能被復制。

問: DB 不能在一個事務中進行刪除和插入是PostgreSQL中的某種限制嗎,因為 PostgreSQL 在執行刪除提交之前不會更新其索引,因此插入將失敗,因為 id 或鍵(無論我們使用什么)已經存在於索引中?

可能的解決方案是什么? 分成兩筆交易?

更新:訂單完全相同。 當我在 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 和 Update 而不是 Delete 解決了這個問題。 我在 Python 上創建了這個過程,但你可以重現它:

  1. 首先,你創建一個臨時表,就像你要插入值的目標表,不同的是這個表在提交后被刪除。

     CREATE TEMP TABLE temp_my_a_b_data (LIKE public.my_a_b_data INCLUDING DEFAULTS) ON COMMIT DROP;
  2. 我創建了一個 CSV(我必須將不同的數據合並到輸入中),其中包含我想在我的表中輸入/插入的值,並且我使用COPY函數將它們插入到 temp_table ( temp_my_a_b_data ) 中。

    我在這篇與 Java 和 COPY PostgreSQL - \copy 命令相關的帖子中找到了這段代碼:

     String query ="COPY tmp from 'E://load.csv' delimiter ','";
  3. 使用 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;`

注意事項:

我不確定,但您可以在不使用前面的步驟、臨時表或從中復制的情況下執行第三步。 您可以只循環遍歷這些值:

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM