2015-10-06 82 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答案 –

相关问题