假設數據極易被修改,整個處理過程加鎖。依賴數據庫鎖機制保證排他性。
| 級別 | 現象 | 鎖類型 |
|---|---|---|
| Read Uncommitted | 髒讀 | 無共享鎖 |
| Read Committed | 不可重複讀 | 寫排他鎖,讀瞬間共享鎖 |
| Repeatable Read | 幻讀 | 讀共享鎖保持到事務結束 |
| Serializable | 全序列化 | 範圍鎖/表鎖 |
鎖粒度:行鎖 > 頁鎖 > 表鎖 > 庫鎖(粒度越細並發越高)
不加鎖,改用版本號/時間戳檢測衝突。適合讀多寫少、長事務場景。
version 欄位(整數/時間戳)WHERE id=? AND version=oldVersion,並 version=version+1Query 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 透明支援),高衝突或需絕對一致性時用悲觀鎖。外部系統寫入時,建議將更新封裝為存儲過程或統一服務入口。