2015-10-06 48 views
0

我使用spring,hibernate和postgreSQL。插入具有唯一屬性的記錄的正確方法

比方說,我有一個表看起來像這樣:

CREATE TABLE test 
(
    id integer NOT NULL 
    name character(10) 
    CONSTRAINT test_unique UNIQUE (id) 
) 

所以總是當我插入記錄的id屬性應該是唯一的

我想知道什麼是插入新的更好的方法記錄(在我的Spring Java應用程序):

1)檢查與給定的ID記錄存在,如果它不插入記錄,這樣的事情:

if(testDao.find(id) == null) { 
    Test test = new Test(Integer id, String name); 
    testeDao.create(test); 
} 

2)調用直創建方法和等待,如果它會拋出的DataAccessException ...

Test test = new Test(Integer id, String name); 
try{ 
    testeDao.create(test); 
} 
catch(DataAccessException e){ 
    System.out.println("Error inserting record"); 
} 

我認爲第一個適當的方式,但它意味着DB更多的處理。你有什麼意見?

非常感謝您的任何建議。

回答

2

選項(2)受制於競爭條件,其中併發會話可以在檢查它並插入它之間創建記錄。此窗口比您預期的要長,因爲該記錄可能已被其他事務插入,但尚未提交。

選項(1)更好,但會在PostgreSQL錯誤日誌中產生很多噪音。

最好的方法是使用PostgreSQL 9.5的INSERT ... ON CONFLICT ...支持來做一個可靠的無競爭條件插入 - 如果不存在的操作。

在舊版本中,您可以在plpgsql中使用循環。

當然,這兩個選項都需要使用本機查詢。

2

取決於您的ID的來源。如果您自己生成它,您可以聲明唯一性並依賴捕捉異常,例如http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html

另一種方法是使用SERIAL數據類型

http://www.postgresql.org/docs/8.1/interactive/datatype.html#DATATYPE-SERIAL

如果你必須從不受信任的來源拿過來,做事先檢查,讓Postgres的生成ID。

+0

在我的案例中,id是從用戶提交的表單中提取的(好吧,它不完全是id,但其他一些列...),所以我應該進行檢查,儘管它意味着更多的「加載」DB,對吧? – Michael

+1

是的,絕對。用戶輸入始終必須被視爲最不受信任的來源。 –

+0

通過事先檢查,您可能仍會遇到異常情況,請參閱Craigs答案 –

相關問題