mybatis事務

什麼是事務(Transaction)?
事務是訪問並可能更新數據庫中各種數據項的一個程序執行單元(unit)。事務通常由高級數據庫操縱語言或編程語言(如SQL,C++或Java)書寫的用戶程序的執行所引起,並用形如begin transaction和end transaction語句(或函數調用)來界定。事務由事務開始(begin transaction)和事務結束(end transaction)之間執行的全體操作組成。

而在實際的應用當中,事務可能只是一條單個的SQL語句,或者是幾條SQL組成,共同執行的。

事務的四大特性ACID
1、原子性(Atomicity)
事務是一個不可分割的單位,事務中的所有SQL等操作要麼都發生,要麼都不發生。
2、一致性(Consistency)
事務發生前和發生後,數據的完整性必須保持一致。
3、隔離性(Isolation)
當併發訪問數據庫時,一個正在執行的事務在執行完畢前,對應其他的會話是不可見的,多個併發事務之間的數據是相互隔離的。備份的參數 --single-transaction
4、持久性(Durability)
 一旦事務提交成功,事務中所有的數據操作都必須被持久化保存到數據庫中,即使提交事務後,數據庫崩潰,在數據庫重啓時,也必須能保證通過某種機制恢復數據。

不考慮隔離性會產生的三個問題
1、髒讀:髒讀是指在一個事務處理過程裏讀取了另一個未提交的事務中的數據。

2、不可重複讀:一個事務兩次讀取同一行的數據,結果得到不同狀態的結果,中間正好另一個事務更新了該數據,兩次結果相異,不可被信任。通俗來講就是:事務T1在讀取某一數據,而事務T2立馬修改了這個數據並且提交事務給數據庫,事務T1再次讀取該數據就得到了不同的結果,發送了不可重複讀。

3、幻讀(虛讀):一個事務執行兩次查詢,第二次結果集包含第一次中沒有或某些行已經被刪除的數據,造成兩次結果不一致,只是另一個事務在這兩次查詢中間插入或刪除了數據造成的。通俗來講就是:例如事務T1對一個表中所有的行的某個數據項做了從“1”修改爲“2”的操作,這時事務T2又對這個表中插入了一行數據項,而這個數據項的數值還是爲“1”並且提交給數據庫。而操作事務T1的用戶如果再查看剛剛修改的數據,會發現還有一行沒有修改,其實這行是從事務T2中添加的,就好像產生幻覺一樣,這就是發生了幻讀
解決辦法:四種隔離級別
1、Read Uncommited(讀取未提交內容)

讀未提交,顧名思義,就是一個事務可以讀取另一個未提交事務的數據。但是,讀未提交產生了髒讀,採用讀提交可以解決髒讀問題

2、Read Commited(讀取提交內容)

讀提交,顧名思義,就是一個事務要等另一個事務提交後才能讀取數據。讀提交,若有事務對數據進行更新(UPDATE)操作時,讀操作事務要等待這個更新操作事務提交後才能讀取數據,可以解決髒讀問題。但在這個事例中,出現了一個事務範圍內兩個相同的查詢卻返回了不同數據,這就是不可重複讀。但是,讀提交兩次查詢會產生不同的查詢結果,就會造成不可重複讀問題,採用重複讀可以解決此問題。

3、Repeatable Read(重複讀)

重複讀,就是在開始讀取數據(事務開啓)時,不再允許修改操作。重複讀可以解決不可重複讀問題。應該明白的一點就是,不可重複讀對應的是修改,即UPDATE操作。但是可能還會有幻讀問題。因爲幻讀問題對應的是插入INSERT操作,而不是UPDATE操作。採用Serializable可以解決幻讀問題

4、Serializable(可串行化)

Serializable 是最高的事務隔離級別,在該級別下,事務串行化順序執行,可以避免髒讀、不可重複讀與幻讀。但是這種事務隔離級別效率低下,比較耗數據庫性能,一般不使用。

【注意】

1、大多數數據庫默認的事務隔離級別是Read committed,比如Sql Server , Oracle。Mysql的默認隔離級別是Repeatable read。

2、隔離級別的設置只對當前鏈接有效。對於使用MySQL命令窗口而言,一個窗口就相當於一個鏈接,當前窗口設置的隔離級別只對當前窗口中的事務有效;對於JDBC操作數據庫來說,一個Connection對象相當於一個鏈接,而對於Connection對象設置的隔離級別只對該Connection對象有效,與其他鏈接Connection對象無關。

3、設置數據庫的隔離級別一定要是在開啓事務之前。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章