插入具有唯一属性的记录的正确方法

时间:2015-10-06 05:24:50

标签: java mysql spring hibernate postgresql

我正在使用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)调用直接create方法并等待它是否会抛出DataAccessException ...

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

我认为第一种方式是合适的,但它意味着更多的DB处理。你有什么看法?

提前感谢您的任何建议。

2 个答案:

答案 0 :(得分:2)

取决于您的身份证明来源。如果您自己生成它,则可以断言唯一性并依赖于捕获异常,例如http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html

另一种方法是让Postgres使用SERIAL数据类型

生成ID

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

如果您必须从不受信任的来源接管,请进行事先检查。

答案 1 :(得分:2)

选项(2)受竞争条件的影响,并发会话可以在检查和插入之间创建记录。此窗口比您预期的要长,因为该记录可能已被另一个事务插入,但尚未提交。

选项(1)更好,但会在PostgreSQL错误日志中产生很多噪音。

最好的方法是使用PostgreSQL 9.5 INSERT ... ON CONFLICT ...支持来执行可靠的,无竞争条件的插入 - 如果不存在操作。

在旧版本中,您可以在plpgsql中使用循环。

当然,这两个选项都需要使用本机查询。