1.資料庫事務的概念
資料庫事務是指由一個或多個SQL語句組成的工作單元,這個工作單元中的SQL語句相互依賴,如果有一個SQL語句執行失敗,就必須撤銷整個工作單元。
在並發環境中,多個事務同時訪問相同的資料資源時,可能會造成各種並發問題,可通過設定資料庫的交易隔離等級來避免,還可採用悲觀鎖和樂觀鎖來解決丟失更新這一併發問題。
資料庫事務必須具備ACID特徵:
A: Atomic原子性,整個事務不可分割,要麼都成功,要麼都撤銷。
C: Consistency一致性,事務不能破壞關係資料的完整性和商務邏輯的一致性,例如轉賬,應保證事務結束後兩個賬戶的存款總額不變。
I: Isolation隔離性,多個事務同時操縱相同資料時,每個事務都有各自的完整資料空間 D: Durability持久性,只要事務成功結束,對資料庫的更新就必須永久儲存下來,即使系
統發生崩潰,重啟資料庫後,資料庫還能恢複到事務成功結束時的狀態。
2.事務邊界聲明
只要聲明了一個事務,資料庫系統就會自動保證事務的ACID特性。
聲明事務包含:
事務的開始邊界
事務的正常結束邊界(commit):提交事務,永久儲存
事務的異常結束邊界(rollback):撤銷事務,資料庫回退到執行事務前的狀態
資料庫支援兩種事務模式:
自動認可模式:每個SQL語句都是一個獨立的事務,資料庫執行完一條SQL語句後,會自動認可事務。
手工提交模式:必須由資料庫的客戶程式顯式指定事務的開始和結束邊界
JDBC Connection類的事務控制方法:
setAutoCommit(boolean autoCommit) 設定是否自動認可事務,預設自動
commit() 提交事務
rollback() 撤銷事務
Hibernate控制事務的方法:
1. 調用sessionFactory不帶參數的openSession方法,從串連池獲得串連,Session自動把串連設為手工提交事務模式。
Session session = sessionFactory.openSession();
若調用帶connection參數的openSession,則需要自己設定手工提交:
connection.setAutoCommit(false);
Session session = sessionFactory.openSession(connection);
2. 聲明事務的開始邊界
Transaction tx = session.beginTransaction();
3. 提交事務
tx.commit();
4. 撤銷事務:
tx.rollback();
一個session可以對應多個事務,但是應優先考慮讓一個session只對應一個事務,當一個事務結束或撤銷後,就關閉session.
不管事務成功與否,最後都應調用session的close關閉session
任何時候一個session只允許有一個未提交的事務,不能同時開始兩個事務
3.多事務並發問題
同時運行多個事務訪問相同資料時,可能會導致5類並發問題:
1. 第一類丟失更新:撤銷一個事務時,把其他事務已提交的更新覆蓋
2. 髒讀:一個事務讀到另一事務未提交的更新資料
3. 虛讀:一個事務讀到另一事務已提交的新插入的資料
4. 不可重複讀取:一個事務讀到另一事務已提交的更新資料
5. 第二類丟失更新:一個事務覆蓋另一事務已提交的更新資料,不可重複讀取的特例
1. 第一類丟失更新:
t1 開始事務
t2 開始事務
t3 查詢存款餘額為1000元
t4 查詢存款餘額為1000元
t5匯入100元,把存款餘額改為1100元
t6提交事務
t7取出100元,把存款餘額改為900元
t8撤銷事務,賬戶的存款餘額恢複為1000元
2. 髒讀:
t1開始事務
t2開始事務
t3查詢存款餘額為1000元
t4
t5取出100元,把存款餘額改為900元
t6查詢賬戶餘額為900元(髒讀)
t7撤銷事務,賬戶的存款餘額恢複為1000元
t8匯入100元,存款餘額改為1000元
t9提交事務
3. 虛讀:
t1開始事務
t2開始事務
t3統計網站註冊人數為1000人
t4註冊一個新使用者
t5提交事務
t6統計網站註冊人數為1000人(虛讀)
t7到底哪個統計資料有效。
4. 不可重複讀取:
t1開始事務
t2開始事務
t3查詢賬戶餘額為1000元
t4查詢賬戶餘額為1000元
t5取出100元,餘額改為900元
t6提交事務
t7查詢賬戶餘額為900元
t8到底餘額是1100元還是900+100元。
5. 第二類丟失更新:
t1開始事務
t2開始事務
t3查詢賬戶餘額為1000元
t4查詢賬戶餘額為1000元
t5取出100元,餘額改為900元
t6提交事務
t7匯入100元,把存款餘額改為1100元
t8提交事務
4.資料庫鎖
資料庫必須具有隔離並發啟動並執行各個事務的能力,資料庫採用鎖來實現事務的隔
離性。
根據資料庫能夠鎖定資源,可分為以下鎖:
資料庫級鎖
表級鎖
地區級鎖
頁面級鎖
索引值鎖: 鎖定資料庫表中帶有索引的一行資料
行級鎖:鎖定資料庫表中的單行記錄
鎖的封鎖粒度越大,隔離性越高,並發性越低
鎖定擴大指調整鎖的粒度,將多個低粒度鎖替換成更高粒度的鎖,以降低系統負荷。
按照封鎖程度,鎖可分為:
共用鎖定:用於讀資料,非獨佔,允許其他事務同時讀取鎖定資源,但不允許其
他事務更新。
加鎖:執行select語句時,資料庫會為事務分配共用鎖定,鎖定被查詢的