[英]Hibernate 2nd level cache ObjectNotFoundException with a high number of concurrent transactions
我們有一個Java應用程序,它使用MySQL,Hibernate(3.5.1-Final)和EHcache(1.2.3)作為我們的二級緩存。
我們的hibernate.properties隔離級別是Read-committed isolation = 2
# 2-Read committed isolation
hibernate.connection.isolation=2
在大量並發事務中,我們看到一個問題,即加載時某些集合(數據庫關聯)將拋出ObjectNotFoundException,並且看起來第二級緩存正在返回該集合的舊副本。
我們有許多不同類型的交易來訪問這個集合(只有閱讀),只有幾個會從中添加/刪除項目。
我們在單個事務負載或甚至中等事務負載(10 - 20個並發連接)下都沒有看到此問題。
例如,我們有一個Character實體:
@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<CharacterItem> items;
我們正在通過從包含它們的集合中刪除實體並調用session.delete()來刪除實體時正確維護對象圖。
character.getItems().remove(characterItem);
session.delete(characterItem);
我們嘗試過更改Set項目; CacheConcurrencyStrategy來自:
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<CharacterItem> items;
至
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<CharacterItem> items;
沒有運氣。
我們不使用數據庫鎖,而是使用樂觀並發控制來捕獲和重試沖突的事務。
目前我們只能看到兩個解決方案:
嘗試捕獲ObjectNotFoundException並嘗試智能地逐出集合(盡管在異常中似乎沒有足夠的上下文)
在items集合上使用@NotFound(action = NotFoundAction.IGNORE)注釋,它將忽略而不拋出ObjectNotFoundException(但是我們關注它如何與二級緩存一起工作並確保它正在查看正確的數據) 。
我希望有一個@NotFound(action = NotFoundAction.EVICT_2ND_LEVEL_CACHE_RELOAD),它將從緩存中驅逐該對象並嘗試重新加載該集合。
我們也可以嘗試將FetchyType從LAZY更改為EAGER,但我想嘗試理解問題,並選擇最佳解決方案,使我們的事務中的數據在高並發性下保持一致。
也許你應該嘗試session.evict(characterItem)
而不是session.delete
?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.