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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

休眠锁定模式– OPTIMISTIC_FORCE_INCREMENT锁定模式如何工作

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

介紹

在我以前的文章中 ,我解釋了OPTIMISTIC鎖定模式是如何工作的,以及它如何幫助我們同步外部實體狀態更改。 在本文中,我們將介紹OPTIMISTIC_FORCE_INCREMENT鎖定模式的使用模式。

使用LockModeType.OPTIMISTIC ,將在當前正在運行的事務結束時檢查鎖定的實體版本,以確保我們不使用陳舊的實體狀態。 由于應用程序級驗證的性質 ,該策略易受競爭條件的影響,因此需要附加的悲觀鎖 。

LockModeType.OPTIMISTIC_FORCE_INCREMENT不僅會檢查預期的鎖定實體版本,還會對其進行遞增。 檢查和更新都發生在同一UPDATE語句中,因此利用了當前數據庫事務隔離級別和關聯的物理鎖定保證。

值得注意的是,即使當前運行的事務未更改實體狀態,鎖定的實體版本也會被提高。

集中版本控制用例

作為練習,我們將模擬一個集中化的版本控制系統 ,其建模如下:

存儲庫是我們的系統根實體,每個狀態更改都由Commit子實體表示。 每個Commit可能包含一個或多個Change組件,這些組件作為單個原子工作單元傳播。

存儲庫版本隨著每個新的Commit而增加。 為簡單起見,我們只驗證存儲庫實體版本,盡管更現實的方法肯定會檢查每個單獨的文件版本(以允許無沖突的提交并發進行)。

測試時間

首先,我們應該檢查OPTIMISTIC_FORCE_INCREMENT鎖定模式是否符合我們的用例要求:

doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {Repository repository = (Repository) session.get(Repository.class, 1L);session.buildLockRequest(new LockOptions(LockMode.OPTIMISTIC_FORCE_INCREMENT)).lock(repository);Commit commit = new Commit(repository);commit.getChanges().add(new Change("README.txt", "0a1,5..."));commit.getChanges().add(new Change("web.xml", "17c17..."));session.persist(commit);return null;} });

此代碼生成以下輸出:

#Alice selects the Repository and locks it using an OPTIMISTIC_FORCE_INCREMENT Lock Mode Query:{[select lockmodeop0_.id as id1_2_0_, lockmodeop0_.name as name2_2_0_, lockmodeop0_.version as version3_2_0_ from repository lockmodeop0_ where lockmodeop0_.id=?][1]} #Alice makes two changes and inserts a new Commit Query:{[select lockmodeop0_.id as id1_2_0_, lockmodeop0_.name as name2_2_0_, lockmodeop0_.version as version3_2_0_ from repository lockmodeop0_ where lockmodeop0_.id=?][1]} Query:{[insert into commit (id, repository_id) values (default, ?)][1]} Query:{[insert into commit_change (commit_id, diff, path) values (?, ?, ?)][1,0a1,5...,README.txt]} Query:{[insert into commit_change (commit_id, diff, path) values (?, ?, ?)][1,17c17...,web.xml]} #The Repository version is bumped up Query:{[update repository set version=? where id=? and version=?][1,1,0]}

我們的用戶選擇了一個存儲庫并發布了一個新的Commit 。 在交易結束時, 存儲庫版本也會增加(因此記錄新的存儲庫狀態更改)。

沖突檢測

在下一個示例中,我們將有兩個用戶(愛麗絲和鮑勃)同時提交更改。 為避免丟失更新 ,兩個用戶都獲得了顯式的OPTIMISTIC_FORCE_INCREMENT鎖定模式。

在Alice獲得提交機會之前,Bob剛剛完成了交易并增加了Repository版本。 Alice事務將回滾,并引發不可恢復的 StaleObjectStateException 。

為了模擬沖突檢測機制,我們將使用以下測試方案:

doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {Repository repository = (Repository) session.get(Repository.class, 1L);session.buildLockRequest(new LockOptions(LockMode.OPTIMISTIC_FORCE_INCREMENT)).lock(repository);executeAndWait(new Callable<Void>() {@Overridepublic Void call() throws Exception {return doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session _session) {Repository _repository = (Repository) _session.get(Repository.class, 1L);_session.buildLockRequest(new LockOptions(LockMode.OPTIMISTIC_FORCE_INCREMENT)).lock(_repository);Commit _commit = new Commit(_repository);_commit.getChanges().add(new Change("index.html", "0a1,2..."));_session.persist(_commit);return null;}});}});Commit commit = new Commit(repository);commit.getChanges().add(new Change("README.txt", "0a1,5..."));commit.getChanges().add(new Change("web.xml", "17c17..."));session.persist(commit);return null;} });

生成以下輸出:

#Alice selects the Repository and locks it using an OPTIMISTIC_FORCE_INCREMENT Lock Mode Query:{[select lockmodeop0_.id as id1_2_0_, lockmodeop0_.name as name2_2_0_, lockmodeop0_.version as version3_2_0_ from repository lockmodeop0_ where lockmodeop0_.id=?][1]} #Bob selects the Repository and locks it using an OPTIMISTIC_FORCE_INCREMENT Lock Mode Query:{[select lockmodeop0_.id as id1_2_0_, lockmodeop0_.name as name2_2_0_, lockmodeop0_.version as version3_2_0_ from repository lockmodeop0_ where lockmodeop0_.id=?][1]} #Bob makes a change and inserts a new Commit Query:{[insert into commit (id, repository_id) values (default, ?)][1]} Query:{[insert into commit_change (commit_id, diff, path) values (?, ?, ?)][1,0a1,2...,index.html]} #The Repository version is bumped up to version 1 Query:{[update repository set version=? where id=? and version=?][1,1,0]} #Alice makes two changes and inserts a new Commit Query:{[insert into commit (id, repository_id) values (default, ?)][1]} Query:{[insert into commit_change (commit_id, diff, path) values (?, ?, ?)][2,0a1,5...,README.txt]} Query:{[insert into commit_change (commit_id, diff, path) values (?, ?, ?)][2,17c17...,web.xml]} #The Repository version is bumped up to version 1 and a conflict is raised Query:{[update repository set version=? where id=? and version=?][1,1,0]} INFO [main]: c.v.h.m.l.c.LockModeOptimisticForceIncrementTest - Failure: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.vladmihalcea.hibernate.masterclass.laboratory.concurrency. LockModeOptimisticForceIncrementTest$Repository#1]

此示例表現出與典型的隱式樂觀鎖定機制相同的行為。 唯一的區別在于版本更改發起者。 雖然隱式鎖定僅適用于修改實體,但是顯式鎖定可以跨任何托管實體使用(忽略實體狀態更改要求)。

結論

因此, OPTIMISTIC_FORCE_INCREMENT對于將子實體狀態更改傳播到未修改的父實體非常有用。 通過簡單地鎖定它們的公共父代,此模式可以幫助我們同步各種實體類型。

當子實體狀態更改必須觸發父實體版本增加時,您可能追求的是顯式OPTIMISTIC_FORCE_INCREMENT鎖定模式。

  • 代碼可在GitHub上獲得 。

翻譯自: https://www.javacodegeeks.com/2015/02/hibernate-locking-patterns-optimistic_force_increment-lock-mode-work.html

總結

以上是生活随笔為你收集整理的休眠锁定模式– OPTIMISTIC_FORCE_INCREMENT锁定模式如何工作的全部內容,希望文章能夠幫你解決所遇到的問題。

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