首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

多線程並發控制:悲觀鎖與樂觀鎖原理、場景與 Hibernate 實戰

     編輯:Java 綜合教學

悲觀鎖:預期衝突,先鎖後用

假設數據極易被修改,整個處理過程加鎖。依賴數據庫鎖機制保證排他性。

數據庫隔離級別與鎖

級別現象鎖類型
Read Uncommitted髒讀無共享鎖
Read Committed不可重複讀寫排他鎖,讀瞬間共享鎖
Repeatable Read幻讀讀共享鎖保持到事務結束
Serializable全序列化範圍鎖/表鎖

鎖粒度:行鎖 > 頁鎖 > 表鎖 > 庫鎖(粒度越細並發越高)

樂觀鎖:預期無衝突,用時檢查

不加鎖,改用版本號/時間戳檢測衝突。適合讀多寫少、長事務場景。

實現機制

  1. 表增加 version 欄位(整數/時間戳)
  2. 讀取時帶出 version
  3. 更新時 WHERE id=? AND version=oldVersion,並 version=version+1
  4. 若影響行數=0 則衝突,拋異常重試

Hibernate 實戰配置

悲觀鎖

Query query = session.createQuery("from TUser where name='Erica'");
query.setLockMode("user", LockMode.UPGRADE); // SELECT ... FOR UPDATE
List list = query.list();

生成 SQL 含 FOR UPDATE,數據庫層面加排他鎖。

樂觀鎖

// 映射文件
<class name="TUser" table="t_user" optimistic-lock="version">
    <version name="version" column="version" type="integer"/>
</class>

// 代碼
Transaction tx = session.beginTransaction();
user.setUserType(1);
tx.commit(); // 自動檢查 version,衝突拋 StaleObjectStateException

optimistic-lock 可選:version(推薦)、dirty(檢查髒字段)、all(檢查所有字段)、none。

兩者對比與選型建議

維度悲觀鎖樂觀鎖
並發性能低(阻塞等待)高(無阻塞,衝突才重試)
適用場景寫多、衝突頻繁、需強一致性讀多、長事務、衝突稀少
外部系統干擾數據庫鎖可防禦無法防禦繞過應用的直接更新
實現複雜度低(數據庫原生)需版本字段、重試邏輯

建議:優先考慮樂觀鎖(Hibernate 透明支援),高衝突或需絕對一致性時用悲觀鎖。外部系統寫入時,建議將更新封裝為存儲過程或統一服務入口。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved