休眠NONSTRICT_READ_WRITE CacheConcurrencyStrategy如何工作
介紹
在我以前的文章中 ,我介紹了READ_ONLY CacheConcurrencyStrategy ,這是不可變實體圖的顯而易見的選擇。 當緩存的數據可變時,我們需要使用讀寫緩存策略,本文將介紹NONSTRICT_READ_WRITE二級緩存的工作方式。
內部運作
提交Hibernate事務后,將執行以下操作序列:
首先,在刷新期間,在提交數據庫事務之前,緩存無效:
提交數據庫事務后,將再次刪除緩存條目:
不一致警告
NONSTRICT_READ_WRITE模式不是“ 直 寫式”緩存策略,因為緩存條目無效,而不是被更新。 緩存無效化與當前數據庫事務不同步。 即使關聯的Cache區域條目兩次無效(在事務完成之前和之后),當緩存和數據庫可能分開時,仍然還有一個很小的時間窗口。
以下測試將演示此問題。 首先,我們將定義Alice事務邏輯:
doInTransaction(session -> {LOGGER.info("Load and modify Repository");Repository repository = (Repository)session.get(Repository.class, 1L);assertTrue(getSessionFactory().getCache().containsEntity(Repository.class, 1L));repository.setName("High-Performance Hibernate");applyInterceptor.set(true); });endLatch.await();assertFalse(getSessionFactory().getCache().containsEntity(Repository.class, 1L));doInTransaction(session -> {applyInterceptor.set(false);Repository repository = (Repository)session.get(Repository.class, 1L);LOGGER.info("Cached Repository {}", repository); }); 愛麗絲加載存儲庫實體,并在她的第一個數據庫事務中對其進行修改。
為了在Alice準備提交時產生另一個并發事務,我們將使用以下Hibernate Interceptor :
運行此代碼將生成以下輸出:
[Alice]: Load and modify Repository [Alice]: select nonstrictr0_.id as id1_0_0_, nonstrictr0_.name as name2_0_0_ from repository nonstrictr0_ where nonstrictr0_.id=1 [Alice]: update repository set name='High-Performance Hibernate' where id=1[Alice]: Fetch Repository from another transaction [Bob]: select nonstrictr0_.id as id1_0_0_, nonstrictr0_.name as name2_0_0_ from repository nonstrictr0_ where nonstrictr0_.id=1 [Bob]: Cached Repository from Bob's transaction Repository{id=1, name='Hibernate-Master-Class'}[Alice]: committed JDBC Connection[Alice]: select nonstrictr0_.id as id1_0_0_, nonstrictr0_.name as name2_0_0_ from repository nonstrictr0_ where nonstrictr0_.id=1 [Alice]: Cached Repository Repository{id=1, name='High-Performance Hibernate'}過時的數據與丟失的更新
當數據庫和二級緩存可能不同步時, NONSTRICT_READ_WRITE并發策略會引入一個很小的不一致窗口。 盡管這聽起來可能很糟糕,但實際上,即使我們不使用二級緩存,也應始終設計應用程序來應對這些情況。 Hibernate通過其事務性的后寫式第一級緩存提供應用程序級可重復讀取,并且所有托管實體都將變得過時。 在將實體加載到當前的持久性上下文中之后 ,另一個并發事務可能會對其進行更新,因此,我們需要防止陳舊的數據升級為丟失的更新 。
樂觀并發控制是處理長時間對話中丟失的更新的有效方法,并且該技術還可以緩解NONSTRICT_READ_WRITE不一致問題。
結論
NONSTRICT_READ_WRITE并發策略是大多數只讀應用程序的不錯選擇(如果由樂觀鎖定機制支持)。 對于寫密集型方案,緩存無效機制將增加緩存未命中率 ,因此使該技術效率低下。
- 代碼可在GitHub上獲得 。
翻譯自: https://www.javacodegeeks.com/2015/05/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work.html
總結
以上是生活随笔為你收集整理的休眠NONSTRICT_READ_WRITE CacheConcurrencyStrategy如何工作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 揭秘5位爬藤“牛娃” 他们吸引藤校的到底
- 下一篇: app engine_Google Ap