1. 程式人生 > >HIbernate——事務併發問題及處理(樂觀鎖悲觀鎖)

HIbernate——事務併發問題及處理(樂觀鎖悲觀鎖)

一、事物併發三種常見問題

1.dirty read 髒讀

時間 事物A 事物B
T1 開始事物 開始事物
T2 查詢賬戶餘額為1000
T3 匯入100把餘額變為1100
T4 讀取賬戶餘額為1100
T5 回滾
T6 取款1100
T7 提交事物失敗

事物A讀到了事物B還沒有提交的資料

2.non-repeatable read 不可重複讀

時間 事物A 事物B
T1 開始事物
T2 開始事物
T3 查詢賬戶餘額為1000
T4 匯入100把餘額變為1100
T5 提交事物
T6
T7 查詢餘額為1100
T8 提交事物

事物A第一次讀餘額為1000,B在中間提交了一次事物把餘額改為了1100,事物A再讀取餘額變為了1100。讀取同一個資料得到了了兩個不同的結果

3.phantom read 幻讀

時間 事物A 事物B
T1 開始事物
T2 開始事物
T3 查詢學生數為10人
T4 插入一個學生
T5 查詢學生數為11人
T6 提交事物
T7 提交事物

事務A執行兩次查詢,第二次結果集包含第一次中沒有或者某些行已被刪除,造成兩次結果不一致,是事務B在這兩次查詢中間插入或者刪除了資料造成的。

不可重複讀和幻讀的區別在與一個是前者強調更新,後者強調插入和刪除。

二、事物隔離機制

1.read uncommitted 可讀未提交
2.read committed 可讀已提交
3.repeatable read 可重複讀
4.serializable 序列化

隔離級別 是否髒讀 是否不可重複讀 是否幻讀
read uncommitted
read committed
repeatable read
serializable

隔離級別越高,效率越低。

一般把事物級別設為2:read committed
如果不設定事物級別,則根據資料庫的預設級別來設定,如MySQL預設級別是repeatable read
這裡寫圖片描述

設定Hibernate的事物隔離機級別

1:read uncommitted;2:read committed;4:repeatable read;8:serializable

<property name="hibernate.connection.isolation">2</property>

三、樂觀鎖和悲觀鎖

當事務隔離級別設為2(read committed)時,任會出現non-repeatable read和phantom read(很少出現,可以忽略)問題。因此我們需要樂觀鎖或悲觀鎖來解決non-repeatable read 問題。

悲觀鎖

悲觀鎖假定當前事務操縱資料資源時,可能會有其他事務同時訪問該資料資源,為了避免當前事務的操作受到干擾,先鎖定資源。儘管悲觀鎖能夠防止丟失更新和不可重複讀這類併發問題,但是它影響併發效能,因此應該很謹慎地使用悲觀鎖。

select … for update

Hibernate3

User u =(User)session.get(User.class,1,LockMode.UPGRADE);

在Hibernate3.6以上的版本中”LockMode”已經不建議使用
Hibernate4

User u =(User)session.get(User.class,1,LockOptions.UPGRADE);

在讀取資料時,藉助資料庫為這條資料上鎖,即在sql語句後加上 for update,在這個事物提交前,其他事物無法對這條資料進行改動。

樂觀鎖

樂觀鎖假定當前事務操縱資料資源時,不會有其他事務同時訪問該資料資源,因此不作資料庫層次上的鎖定。為了維護正確的資料,樂觀鎖使用應用程式上的版本控制(由程式邏輯來實現的)來避免可能出現的併發問題。

private int version;
@Version
    public int getVersion() {
        return version;
    }
    public void setVersion(int version) {
        this.version = version;
    }

在表裡加上一個version欄位,記錄當前的版本號,更新資料時version會加1。將提交資料的版本號與資料庫表對應記錄的當前版本號進行比對,如果提交的資料版本號大於資料庫表當前版本號,則更新,否則就報錯。
比如
事物A取出一條記錄,當前版本號為0,更改記錄後版本號增加1。如果在事物A提交前有個事物B更新了該資料,資料庫內的版本號變為了1,A再提交時就會報錯。

相關推薦

HIbernate——事務併發問題處理樂觀悲觀

一、事物併發三種常見問題 1.dirty read 髒讀 時間 事物A 事物B T1 開始事物 開始事物 T2 查詢賬戶餘額為1000 T3 匯入100把餘額變為1100 T4

多執行緒與高併發基礎一超發--悲觀樂觀

關鍵詞: 執行緒,同步,單例,高併發,高訪問,死鎖 一、大規模併發帶來的挑戰 在過去的工作中,我曾經面對過5w每秒的高併發秒殺功能,在這個過程中,整個Web系統遇到了很多的問題和挑戰。如果Web系統不做針對性的優化,會輕而易舉地陷入到異常狀態。我們現在一起來討論下

Hibernate事務併發問題處理悲觀樂觀

Hibernate悲觀鎖:在資料有載入的時候就給其進行加鎖,直到該鎖被釋放掉,其他使用者才可以進行修改; Hibernate樂觀鎖:在對資料進行修改的時候,對資料才去版本或者時間戳等方式來比較,資料是否一致性來實現加鎖。 我們在使用Hibernate中經常用到當多個人對同一資料同時進行修改的時候,會發

python資料庫併發處理樂觀

1.資料庫併發處理問題 在多個使用者同時發起對同一個資料提交修改操作時(先查詢,再修改),會出現資源競爭的問題,導致最終修改的資料結果出現異常。 比如限量商品在熱銷時,當多個使用者同時請求購買商品時,最終修改的資料就會出現異常  下面我們來寫點程式碼還原一下現象: 1

JAVA併發 - 悲觀VS樂觀

文章目錄 悲觀鎖VS樂觀鎖 1.悲觀鎖 1.1什麼是悲觀鎖 1.2原始碼分析 synchronized Lock 1.3應用場景 1.4實現

Java高效併發樂觀悲觀互斥同步、非互斥同步

樂觀鎖和悲觀鎖 首先我們理解下兩種不同思路的鎖,樂觀鎖和悲觀鎖。 這兩種鎖機制,是在多使用者環境併發控制的兩種所機制。下面看百度百科對樂觀鎖和悲觀鎖兩種鎖機制的定義: 樂觀鎖( Optimistic Locking ) 相對悲觀鎖而言,樂觀鎖機制採取了更加寬鬆的加鎖

Java併發基礎-的使用原理可重入、讀寫、內建、訊號量等

本文目錄: 1 基礎 1.1 可重入鎖 可重入鎖表示的是,如果一個執行緒在未釋放已獲得鎖的情況下再次對該物件加鎖,將可以加鎖成功。而且可以不斷的加鎖成功多次。但需要注意的是,每次加鎖操作必須對應著一次釋放鎖的操作。 如以下示例是可以執行的(

【轉】MySQL sql_mode 說明處理一起 sql_mode 引發的問題

出錯 異常 set .cn ava 失敗 sub class 習慣 1. MySQL 莫名變成了 Strict SQL Mode 最近測試組那邊反應數據庫部分寫入失敗,app層提示是插入成功,但表裏面裏面沒有產生數據,而兩個寫入操作的另外一個表有數據。因為 insert 失

Tsi721訊號處理

reference: https://blog.csdn.net/shanghaiqianlun/article/details/50545581 1.      PCIe訊號

事務 悲觀 樂觀 概念 應用場景 使用方式 小記

【部落格園cnblogs筆者m-yb原創(部分引用, 在文末有註明),轉載請加本文部落格連結,筆者github: https://github.com/mayangbo666,公眾號aandb7,QQ群927113708】  https://www.cnblogs.com/m-yb/p/99749

SpringBoot全域性異常捕獲處理包括自定義異常捕獲處理

在做專案的時候需要對自定義異常做捕獲和處理,現在將程式碼記錄下來便於以後查閱。 1、全域性異常捕捉處理 @ControllerAdvice( annotations = {RestController.class} ) public class ExceptionHandlerAdv

Hibernate事務操作session與本地執行緒繫結

事務相關概念   1 什麼是事務     事務是應用程式中一系列嚴密的操作,所有操作必須成功完成,否則在每個操作中所作的所有更改都會被撤消。也就是事務具有原子性,一個事務中的一系列的操作要麼全部成功,要麼一個都不做。     事務的結束有兩種,當事務中的所以步驟全部成功執行時,事務提交。如果其中

資料庫 樂觀/悲觀 的介紹應用

在處理併發問題時,我們會經常遇到以下2點問題 更新丟失. 如:使用者A把值從 ‘一等獎’ 改為 ‘二等獎’,使用者B把值從 ‘一等獎’ 改為 ‘三等獎’,則使用者A的更新被覆蓋. 髒讀. 如:使用者A,B看到的值都是 ‘一等獎’ ,使用者B把值改為 ‘二等獎

Java併發 行級/欄位/表級 樂觀/悲觀 共享/排他[轉]

前言 鎖是防止在兩個事務操作同一個資料來源(表或行)時互動破壞資料的一種機制。 資料庫採用封鎖技術保證併發操作的可序列性。 以Oracle為例: Oracle的鎖分為兩大類:資料鎖(也稱DML鎖)和字典鎖。 字典鎖是Oracle DBMS內部用於對字典表的封鎖。 字典鎖包括語

常見網路安全問題處理xss和csrf

強調內容## 1、XSS(Cross Site Script) 把token儲存在cookie中,同時設定httpOnly。 2、CSRF(cross-site request forgery) 2.1、判斷reffer。系統改動最小,通過filt

Java異常的捕獲處理throws關鍵字

·throws關鍵字主要用於方法宣告上,指的是當前方法之中異常後交給被呼叫處處理;範例1:class MyMath { public static int div(int x, int y) thro

C#資料庫事務原理實踐

另一個走向極端的錯誤 滿懷信心的新手們可能為自己所掌握的部分知識陶醉不已,剛接觸資料庫庫事務處理的準開發者們也一樣,躊躇滿志地準備將事務機制應用到他的資料處理程式的每一個模組每一條語句中去。的確,事務機制看起來是如此的誘人——簡潔、美妙而又實用,我當然想用它來避免一切可能

eclipse常見異常彙總處理持續更新

eclipse總有這樣或那樣奇怪的異常,讓我感到處理起來相當棘手,所以將見過的難以處理的問題彙總一下,以做參考 1. 程式無法啟動 報警: Cannot run program "C:\Program Files\Java\jdk1.6.0_17\bin\javaw.ex

hibernate版本控制 樂觀悲觀

//1: 資料庫表 people 加上一列  version int //2:  實體類  people 屬性 ( private  int version;) //3:  在hibernate 對映檔案class 之間  在一個表示副 id 之後加上  <version    cloumn="vers

TypeHandler簡介配置mybatis源碼篇

java rtt 當我 mes ons byte[] throws call dstat 作者:南柯夢 Mybatis中的TypeHandler是什麽?   無論是 MyBatis 在預處理語句(PreparedStatement)中設置一個參數時,還是從結果集中取出一