mysql事務

在看mysql事務的過程中,看了很多別人的優秀博客,這篇博客中大部分都是看了別人的博客把自己能夠理解的給寫了下來,若有錯誤請指正。

事務的四個條件:(ACID)

A(原子性):在一個事務裏的操作,只有兩種可能,一是全部順利完成,二是全部都沒完成,後者出現的情況是在執行事務中出錯了,然後會回滾到事務執行前的狀態。
C(一致性):在事務執行前後,數據庫的完整性未被破壞,數據庫的狀態一定是一致的。這裏抄了一段別人的話,比較好理解:對於這個概念,它的第一層意思就是對於數據完整性的約束,包括主鍵約束、引用約束以及一些約束檢查等等,在事務的執行的前後以及過程中不會違背對數據完整性的約束,所有對數據庫寫入的操作都應該是合法的,並不能產生不合法的數據狀態。而第二層意思其實是指邏輯上的對於開發者的要求,我們要在代碼中寫出正確的事務邏輯,比如銀行轉賬,事務中的邏輯不可能只扣錢或者只加錢,這是應用層面上對於數據庫一致性的要求。
I(隔離性):就是多個併發事務執行時,他們是互不干擾的,不會因爲某個事務干擾到其他事務的執行結果。事務隔離的四個級別:讀未提交、讀提交、可重複讀、串行化。
D(持久性):事務執行完後,其對數據的修改是永久的。

事物的使用:

Begin開啓事務,commit提交,即執行begin到commit之間的語句。
Rollback是回滾,即回滾到事務執行前的狀態,期間的任何未提交的修改都會被撤回。
Savepoint identifier,就是在事務中創建保存點。
Release savepoint identifier,顧名思義就是刪除事務中的保存點。
Rollback to identifier,把事務回滾到保存點的狀態。
Set transaction,設置事物的隔離級別,對應隔離性中講到的四個隔離級別。

mysql中對執行的語句進行回滾是通過回滾日誌實現的,事務進行的修改會記錄在其中,之後纔對數據庫中的對應行寫入。簡單來說就是有個日誌會記錄你的可能會影響數據庫的操作,萬一有什麼錯誤,類似於數據庫崩潰阿之類的,就可以利用日誌來查看事務的狀態,當然我們得對日誌進行持久化到磁盤上,萬一重啓了還能夠利用日誌來查看事務的狀態。
利用日誌回滾其實就是執行與修改相反的語句,比如記錄了insert,那麼則執行對應的delete,記錄了update,就執行相反的update。

事物的三個狀態:

執行中、執行完成、執行失敗。

事務一旦提交後則不能夠被回滾。如果要想回到事務提交前的狀態則需要利用重做日誌,在每次事務對數據進行修改時,都會生成重做日誌並寫入重做日誌緩存,在事務被提交時,纔會把重做日誌緩存給刷新到重做日誌文件中。

回滾日誌與重做日誌的區別:

回滾日誌是對事務的影響進行撤銷。事物的原子性與持久性就是由混滾日誌保證的。
重做日誌是對已經提交的事務進行重做,它能夠對發生錯誤與需要回滾的事務進行回滾。在事務提交後若數據還沒寫入磁盤中發生宕機的話能夠在重新啓動後恢復數據。
兩者合在一起就是事務日誌,能進行回滾和重做。

併發事務的情況下:

若在事務並行執行的情況下,事務可能會存在一些複雜的情況,比如一個事務1對錶1進行了操作,而事務2也對錶1進行了操作,並且兩個事務都進行了提交,若要對事務1進行回滾的話,必須先要對事務2進行回滾,因爲得保持事務的原子性,這樣事務2就依賴於事務1的執行,這樣的回滾稱爲級聯回滾,在這種情況下其實要利用隔離性中的鎖。
隔離性的實現,就是對併發的控制,這裏需要用到鎖,鎖一般分爲讀鎖和寫鎖,比如有一個事務對數據進行修改,就會獲得一個寫鎖,其他事務想對這個數據進行修改的話,就必須等待這個寫鎖釋放後才行。有了鎖便不會發生級聯回滾了。

總結:

原子性對於事務的執行是必要的,ACID中的一致性不僅是對於數據庫完整性的要求也是對開發者的邏輯設計要求,隔離性保證併發不會出現太多過錯,但是完全保證隔離性的話會對性能有影響,在實際開發需求中,要對隔離性進行合適的調整,持久性保證我們的數據是持久的,不會丟失。
參考博客:https://draveness.me/mysql-transaction

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