2015-10-06 2 views
0

Я использую spring, hibernate и postgreSQL.Правильный способ вставки записи с уникальным атрибутом

Скажем, у меня есть таблица вида:

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

Так всегда, когда я вставить запись атрибут ID должен быть уникальным

Я хотел бы знать, что это лучший способ, чтобы вставить новый запись (в моем весеннем Java приложение):

1) Проверьте, если запись с заданным идентификатором существует, и если он не вставляет записи, что-то вроде этого:

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

Я считаю, что 1-й путь уместно, но это означает больше обработки для БД. Каково твое мнение?

Заранее благодарю за любой совет.

ответ

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

Другой способ позволить Postgres генерировать идентификатор, используя тип данных SERIAL

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

Если вы должны взять на себя из ненадежного источника, сделайте предварительную проверку.

+0

В моем случае идентификатор берется из формы, представленной пользователем (ну его не точно id, но какой-то другой столбец ...), поэтому я должен сделать чек, несмотря на то, что это означает больше «загрузки» для БД, правильно? – Michael

+1

Да, абсолютно. Пользовательский вход всегда должен считаться наименее надежным источником. –

+0

С предварительной проверкой вы все равно можете столкнуться с исключением tho, см. Ответ Craigs –