У нас есть JAVA-приложение, которое использует MySQL, Будьте в спящем режиме (С 3.5.1 финалом) и EHcache (1.2.3) для нашего 2-го кэша уровня.
Наш hibernate.properties уровень изоляции является фиксировавшей Чтению изоляцией = 2
# 2-Read committed isolation
hibernate.connection.isolation=2
Под высоким количеством параллельных транзакций мы видим проблему, где определенные наборы (ассоциации DB) при загрузке бросят ObjectNotFoundException, и кажется, что 2-й кэш уровня возвращает старую копию того набора.
У нас есть много различных типов транзакций, которые получают доступ к этому набору (только читающий) и только пара, которая добавит/удалит объекты от него.
Мы не видим эту проблему при единственной загрузке транзакции или даже модерируем загрузку транзакции (10 - 20 параллельных соединений).
Например, у нас есть Символьная сущность:
@Entity
@Table(name = "CHARACTERS")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Character extends AbstractCharacter implements Serializable {
...
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@OneToMany(mappedBy = "character", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set items;
Мы правильно поддерживаем граф объектов при удалении объектов путем удаления их из набора, что они содержатся в и звонящий session.delete ().
character.getItems().remove(characterItem);
session.delete(characterItem);
Мы попытались изменить объекты Набора; CacheConcurrencyStrategy от:
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set items;
Кому:
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set items;
Без удачи.
Мы не используем блокировки базы данных вместо этого, мы используем управление оптимистичным параллелизмом, чтобы поймать и повторить конфликтующие транзакции.
Эти только 2 решения, которые мы видим в этой точке, к:
Попытайтесь поймать ObjectNotFoundException и попытаться разумно выселить набор (хотя, кажется, нет достаточного количества контекста в исключении),
Используйте @NotFound (action=NotFoundAction. ПРОИГНОРИРУЙТЕ), аннотация на набор объектов, который проигнорирует и не бросит ObjectNotFoundException (но у нас есть проблемы относительно того, как это работает с 2-м кэшем уровня, и удостоверьтесь, что это смотрит на надлежащие данные).
Мне жаль, что не было @NotFound (action=NotFoundAction. EVICT_2ND_LEVEL_CACHE_RELOAD), где это выселило бы тот объект из кэша и попытки перезагрузить набор.
Мы могли также попытаться изменить FetchyType от ЛЕНИВОГО до НЕТЕРПЕЛИВОГО, но я хочу попытаться понять проблему и выбрать лучшее решение, которое обеспечит, что данные в наших транзакциях последовательны под высоким параллелизмом.
Может быть, вам стоит попробовать session.evict(characterItem)
вместо session.delete
?