HibernateNONSTRICT_READ_WRITE CacheConcurrencyStrategy如何工作
介紹
在我以前的文章中 ,我介紹了READ_ONLY CacheConcurrencyStrategy ,這是不可變實(shí)體圖的顯而易見的選擇。 當(dāng)高速緩存的數(shù)據(jù)可變時(shí),我們需要使用讀寫高速緩存策略,本文將介紹NONSTRICT_READ_WRITE二級(jí)高速緩存的工作方式。
內(nèi)部運(yùn)作
提交Hibernate事務(wù)后,將執(zhí)行以下操作序列:
首先,在刷新期間,在提交數(shù)據(jù)庫(kù)事務(wù)之前,緩存無效:
提交數(shù)據(jù)庫(kù)事務(wù)后,將再次刪除緩存條目:
不一致警告
NONSTRICT_READ_WRITE模式不是“ 直 寫式”緩存策略,因?yàn)榫彺鏃l目無效,而不是被更新。 緩存無效化與當(dāng)前數(shù)據(jù)庫(kù)事務(wù)不同步。 即使關(guān)聯(lián)的Cache區(qū)域條目?jī)纱螣o效(在事務(wù)完成之前和之后),當(dāng)緩存和數(shù)據(jù)庫(kù)可能分開時(shí),仍然存在一個(gè)很小的時(shí)間窗口。
以下測(cè)試將演示此問題。 首先,我們將定義Alice事務(wù)邏輯:
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); }); 愛麗絲加載一個(gè)存儲(chǔ)庫(kù)實(shí)體,并在她的第一個(gè)數(shù)據(jù)庫(kù)事務(wù)中對(duì)其進(jìn)行修改。
為了在Alice準(zhǔn)備提交時(shí)產(chǎn)生另一個(gè)并發(fā)事務(wù),我們將使用以下Hibernate Interceptor :
運(yùn)行此代碼將生成以下輸出:
[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'}過時(shí)的數(shù)據(jù)與丟失的更新
當(dāng)數(shù)據(jù)庫(kù)和二級(jí)緩存可能不同步時(shí), NONSTRICT_READ_WRITE并發(fā)策略會(huì)引入一個(gè)很小的不一致窗口。 盡管這聽起來可能很糟糕,但實(shí)際上,即使我們不使用二級(jí)緩存,也應(yīng)始終設(shè)計(jì)應(yīng)用程序來應(yīng)對(duì)這些情況。 Hibernate通過其事務(wù)性的后臺(tái)寫式第一級(jí)緩存提供應(yīng)用程序級(jí)可重復(fù)讀取,并且所有托管實(shí)體都將變得過時(shí)。 在實(shí)體加載到當(dāng)前的持久性上下文中之后 ,另一個(gè)并發(fā)事務(wù)可能會(huì)對(duì)其進(jìn)行更新,因此,我們需要防止陳舊數(shù)據(jù)升級(jí)為丟失更新 。
樂觀并發(fā)控制是處理長(zhǎng)時(shí)間對(duì)話中丟失的更新的有效方法,該技術(shù)還可以緩解NONSTRICT_READ_WRITE不一致問題。
結(jié)論
NONSTRICT_READ_WRITE并發(fā)策略是大多數(shù)只讀應(yīng)用程序的理想選擇(如果由樂觀鎖定機(jī)制支持)。 對(duì)于寫密集型方案,緩存無效機(jī)制將增加緩存未命中率 ,因此使該技術(shù)效率低下。
- 代碼可在GitHub上獲得 。
翻譯自: https://www.javacodegeeks.com/2015/05/how-does-hibernate-nonstrict_read_write-cacheconcurrencystrategy-work.html
總結(jié)
以上是生活随笔為你收集整理的HibernateNONSTRICT_READ_WRITE CacheConcurrencyStrategy如何工作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是重金属离子 什么叫重金属离子
- 下一篇: 502无法解析服务器标头_编写下载服务器