日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

休眠NONSTRICT_READ_WRITE CacheConcurrencyStrategy如何工作

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 休眠NONSTRICT_READ_WRITE CacheConcurrencyStrategy如何工作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

介紹

在我以前的文章中 ,我介紹了READ_ONLY CacheConcurrencyStrategy ,這是不可變實體圖的顯而易見的選擇。 當緩存的數據可變時,我們需要使用讀寫緩存策略,本文將介紹NONSTRICT_READ_WRITE二級緩存的工作方式。

內部運作

提交Hibernate事務后,將執行以下操作序列:

首先,在刷新期間,在提交數據庫事務之前,緩存無效:

  • 當前的Hibernate事務 (例如JdbcTransaction , JtaTransaction )已刷新
  • DefaultFlushEventListener執行當前的ActionQueue
  • EntityUpdateAction調用EntityRegionAccessStrategy的更新方法
  • NonStrictReadWriteEhcacheCollectionRegionAccessStrategy將從基礎EhcacheEntityRegion中刪除緩存條目
  • 提交數據庫事務后,將再次刪除緩存條目:

  • 完成回調后當前的Hibernate Transaction被調用
  • 當前會話將此事件傳播到其內部ActionQueue
  • EntityUpdateAction在EntityRegionAccessStrategy上調用afterUpdate方法
  • NonStrictReadWriteEhcacheCollectionRegionAccessStrategy調用基礎EhcacheEntityRegion上的remove方法
  • 不一致警告

    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 :

    private AtomicBoolean applyInterceptor = new AtomicBoolean();private final CountDownLatch endLatch = new CountDownLatch(1);private class BobTransaction extends EmptyInterceptor {@Overridepublic void beforeTransactionCompletion(Transaction tx) {if(applyInterceptor.get()) {LOGGER.info("Fetch Repository");assertFalse(getSessionFactory().getCache().containsEntity(Repository.class, 1L));executeSync(() -> {Session _session = getSessionFactory().openSession();Repository repository = (Repository) _session.get(Repository.class, 1L);LOGGER.info("Cached Repository {}", repository);_session.close();endLatch.countDown();});assertTrue(getSessionFactory().getCache().containsEntity(Repository.class, 1L));}} }

    運行此代碼將生成以下輸出:

    [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'}
  • Alice獲取存儲庫并更新其名稱
  • 調用定制的Hibernate Interceptor并啟動Bob的事務
  • 由于存儲庫已從緩存中逐出,因此Bob將使用當前數據庫快照加載第二級緩存
  • Alice事務已提交,但是現在緩存包含Bob剛剛加載的先前數據庫快照
  • 如果第三位用戶現在將獲取存儲庫實體,那么他還將看到與當前數據庫快照不同的陳舊實體版本。
  • 提交Alice事務后,將再次逐出Cache條目,并且任何后續實體加載請求都將使用當前數據庫快照填充Cache
  • 過時的數據與丟失的更新

    當數據庫和二級緩存可能不同步時, 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如何工作的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。