事務併發的五類問題
- 第一類丟失更新:兩個事務同時更新一個數據,A提交,B回滾,數據回滾
- 第二類 丟失更新:兩個數據同時關係一個數據,A晚提交,B早提交,B無效
- 髒讀:一個事務內,讀取了事務B未提交的數據.(結果事務B回滾,該事務就用了髒數據)
- 虛讀:一個事務內,前後讀取不一致,(期間有人增加過數據)
- 不可重複讀:一個事務內兩次讀取同一條數據,返回結果不相同.(期間有人修改過該數據)
MySQL的隔離級別
Serializable(串行化):可避免髒讀、不可重複讀、虛讀情況的發生。
Repeatable read(可重複讀):可避免髒讀、不可重複讀情況的發生。(默認)
Read committed(讀已提交):可避免髒讀情況發生。
Read uncommitted(讀未提交):最低級別,以上情況均無法保證。
悲觀鎖
原理:事務不併發.
事務A開始後,拿到鎖.直至回滾或提交才放鎖.其他事務無鎖就一直等待(不提交,造成死鎖),等同於: select for update
例1:
事務1:
Employee e1=session.get(Employee.class,1L,LockOptions.UPGRADE);//對該對象上鎖
事務2:
Employee e1=session.get(Employee.class,1L);
e1.setName("XX");//執行修改時候被鎖住
例2:
事務1:
Employee e1=session.get(Employee.class,1L,LockOptions.UPGRADE);//對該對象上鎖
事務2:
Employee e1=session.get(Employee.class,1L,LockOptions.UPGRADE);//查詢時候被鎖住
e1.setName("XX");//不會到這一步
樂觀鎖
原理:支持併發:在類加屬性,在表中加列 表示版本號
在查詢對象時候,獲得版本號;
在修改對象時, 版本號+1 where id=? AND 版本號=?;
此時,若版本號不一致,說明已經被更換數據,會導致本次更改失敗
例:
//在類中
private Integer version;
//映射文件中
<version name="version"/>