2013-02-23 6 views
0

У меня есть два приложения, которые используют одну и ту же библиотеку для работы с базой данных. Первое приложение - настольное, а второе - веб. Таким образом, оба из них могут одновременно изменить одну и ту же запись в моей базе данных (PostgreSql). Библиотека использует этот код:JPA EntityManager default merge behavior

//it doesnt use em.getTransaction() 
em.merge(userAcc);//change useraccount 

Может ли этот код вызвать взаимоблокировку? Что такое поведение слияния по умолчанию? Использует ли слияние транзакцию внутри? На самом деле порядок двух операций слияния не имеет значения.

ответ

1

Релевантная цитата из Java Persistence wikibook.

Технически в JPA EntityManager находится в транзакции от созданной точки. Поэтому начало несколько избыточно. Пока не будет вызвано начало, некоторые операции, такие как persist, merge, remove, не могут быть вызваны. Запросы все еще могут выполняться, и объекты, которые были запрошены, могут быть изменены, хотя это несколько неуказано, что произойдет с этими изменениями в спецификации JPA, как правило, они будут зафиксированы, однако лучше всего называть начало, прежде чем вносить какие-либо изменения в ваш объекты.

Похоже, что в этом случае поведение merge() будет зависеть от вашего поставщика непрерывности.

Я предполагаю, что объект все равно будет обновляться в неявной транзакции, но я не думаю, что это может вызвать тупик. В худшем случае сценарий заключается в том, что одновременное обновление одного и того же объекта из ваших двух приложений будет переопределять друг друга, не зная об этом. Это можно предотвратить, используя оптимистичную блокировку.

+0

Так что если он использует транзакции внутри того уровня текущей изоляции. – bossman

+0

Спецификация JPA не определяет уровень изоляции по умолчанию. Он будет определяться базовой базой данных и поставщиком сохранения. – zagyi

Смежные вопросы