Создайте новый или обновите существующий объект в, каждый идет с JPA

Объекта JPA, который имеет поле метки времени и отличен сложным полем идентификатора. То, в чем я нуждаюсь, должно обновить метку времени в объекте, который был уже сохранен, иначе создает и снабжает новый объект текущей меткой времени.

Как оказалось, задача не так проста, как это кажется от первого взгляда. Проблема состоит в том, что в параллельной среде я получаю противное "Исключение" нарушения уникального индекса или первичного ключа. Вот мой код:

// Load existing entity, if any.
Entity e = entityManager.find(Entity.class, id);
if (e == null) {
  // Could not find entity with the specified id in the database, so create new one.
  e = entityManager.merge(new Entity(id));
}
// Set current time...
e.setTimestamp(new Date());
// ...and finally save entity.
entityManager.flush();

Обратите внимание на то, что в этом объекте в качестве примера идентификатор не сгенерирован на вставке, это известно заранее.

Когда два или больше из потоков выполняют этот блок кода параллельно, они могут одновременно добраться null от entityManager.find(Entity.class, id) вызов метода, таким образом, они попытаются сохранить два или больше объекта одновременно с тем же идентификатором, заканчивающимся по ошибке.

Я думаю, что существует немного решений проблемы.

  1. Уверенный я мог синхронизировать этот блок кода с глобальной блокировкой для предотвращения параллельного доступа к базе данных, но это будет самый эффективный путь?
  2. Некоторая очень удобная поддержка баз данных MERGE оператор, который обновляет существующий или создает новую строку, если ни один не существует. Но я сомневаюсь, что OpenJPA (реализация JPA моего выбора) поддерживает его.
  3. Событие, если JPA не поддерживает СЛИЯНИЕ SQL, я могу всегда отступать к простому JDBC и делать то, что я хочу с базой данных. Но я не хочу оставлять удобный API и путаницу с волосатой комбинацией JDBC+SQL.
  4. Существует волшебный прием для фиксации его с помощью стандартного API JPA только, но я еще не знаю это.

Помогите.

9
задан Alex Radzivanovich 25 February 2010 в 08:21
поделиться

1 ответ

Вы имеете в виду изоляцию транзакций для транзакций JPA. Т.е. как ведут себя транзакции, когда они обращаются к ресурсам других транзакций.

Согласно этой статье :

READ_COMMITTED - ожидаемый уровень изоляции транзакции по умолчанию для использования [..] EJB3 JPA

Это означает, что - да, у вас будут проблемы с приведенным выше кодом .

Но JPA не поддерживает настраиваемые уровни изоляции.

В этой ветке эта тема обсуждается более подробно. В зависимости от того, используете ли вы Spring или EJB, я думаю, вы можете использовать правильную стратегию транзакций.

1
ответ дан 3 November 2019 в 09:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: