2014-10-15 4 views
0
CacheId aci = new CacheId(); 
aci.setId(cacheObject.getId()); 
aci.setSequence(cacheObject.getSequence()); 
Cache persisted = em.find(Cache.class, aci); 
if (persisted == null){ 
    System.out.println("========== PERSISTING"); 
    em.persist(cacheObject); 
}else{ 
    System.out.println("========== MERGING"); 
    em.merge(cacheObject); 
} 

В то время как при запуске моего проекта другой экземпляр удаляет запись с текущим CacheId. Теперь мне нужно установить новое значение в базу данных с таким же идентификатором кеша. Но когда я делаю em.find(), это не возвращает null. (но в записи базы данных уже удалено.Таким образом, это приведет к слиянию слияния. И слияние завершилось неудачей с попыткой обновить 1, но обновлено 0 ...Персональный объект, прошедший для сохранения

Но если я прекратил проверку поиска и переадресации всегда, «Отдельный объект передан для сохранения». Как я могу обойти эту проблему?

ответ

0

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

Вы также можете использовать пессимистический шаблон блокировки, используя:

Cache persisted = em.find(Cache.class, aci, LockModeType.PESSIMISTIC_WRITE); 

(или LockModeType.PESSIMISTIC_READ). Блокировка немедленно получается из базы данных, то есть вы сразу узнаете, если данные были удалены. И как только блокировка будет получена, никакая другая транзакция не будет удалена.

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

Но ОЖИДАЙТЕ: приложение должно зафиксировать как можно скорее освобождение блокировки, чтобы избежать возможных взаимоблокировок или ненужной блокировки других транзакций.

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