對事務的理解

什么是事務?

事務是數據庫管理系統執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成。事物的操作要么完全地執行,要么完全地不執行。

在關系數據庫中,一個事務可以是一條SQL語句,一組SQL語句或整個程序。事務有ACID四個特性:

1、原子性(Atomicity):即不可分割,要么全部執行,要么全部不執行。事務的正確執行會使數據庫從一種狀態轉換成另一種狀態,所以如果事務的所有的子事務都提交成功,那么事務成功執行,數據庫狀態發生變化;如果事務中的任何一個子事務提交失敗,那么事務失敗,之前所有執行的子事務都會被回滾,數據庫回到事務執行前的狀態

2、一致性(consistency):事務的執行必須是使數據庫從一種正確的狀態轉移到另外一種正確的狀態

3、隔離性(isolation):在事務完全執行成功之前,不對其他的事務產生影響,也不會受到其他事務的影響

4、持久性(durability):即事務在成功提交后,他對數據庫的改變是永久的,即使數據庫發生災難性的故障,也能夠通過數據庫操作日志和數據備份找回原有的數據。

 

事務的作用

數據庫的事務:

1、他能夠為數據庫操作提供了一個從失敗恢復到正常狀態的方法

2、當多個應用程序并發訪問數據庫時,能夠在這些應用程序提供一個隔離方法,能夠防止各個應用之間的操作互相干擾

系統的事務:

1、對業務進行一系列的操作時,要么全部執行,要么全部不執行

 

事務在并發情況下帶來的問題

事務在為數據庫操作帶來很多便利的同時,也帶來了許多問題。

1、臟讀(針對未提交數據):事務A對某一條數據進行了操作,但是并未提交,此時事務B讀取到了事務A還未提交的操作后的該條數據,如果事務A發生回滾,事務B讀到的數據就是錯誤的,這種現象被稱為臟讀

具體例子:灰太狼查看自己家里銀行卡里的存款(卡里擁有5000元),灰太狼查看存款(事務A開啟),同時紅太狼進行取款(事務B開啟),取走1000元(事務B并未提交),此時灰太狼查看到的存款為4000元(查看到了紅太狼取完款后的銀行卡余額,事務A結束),但是紅太狼又將1000元存回去(事務B結束),實際上此時卡里還有5000元,但是灰太狼誤以為只有4000元,這就是一種典型的臟讀現象。

2、不可重復讀(針對其他事物提交前后,讀取數據本身的對比):事務A讀取到了某一條數據,然后事務A執行他的邏輯,此時事務B修改了該條數據,事務A再次讀取到該條數據時,發現和第一次讀取到的數據不一致,這種現象被稱為不可重復讀

具體例子:灰太狼查看自己家里銀行卡里的存款(卡里擁有5000元),灰太狼查看存款(事務A開啟),查看到存款為5000元,同時紅太狼進行取款(事務B開啟),取走1000元(事務B結束),然后灰太狼再次查看存款為4000元(事務A結束),在同一個事務內兩次讀到的銀行卡余額不同,這就是一種典型的不可重復讀現象。

3、幻讀(針對其他事物提交前后,讀取數據條數的對比):事務A讀取到了符合一個條件的某幾條(N條)數據,事務B增添了符合該條件的(M條)幾條數據,并提交,事務A再次讀取符合該條件的數據時,讀到的條數為(N+M條)與第一次讀取到的條數不相等,這種現象被稱為幻讀

具體例子:灰太狼抓到了幾只羊,出門買調料前,數了一遍鍋里的羊(事務A開啟),有3只,就出門了。灰太狼出門后紅太狼又從羊村抓了2只羊回來放到鍋里(事務B),灰太狼回家后數了一下鍋里的羊,有5只羊,灰太狼還以為自己第一次數錯了,這便是一種典型的幻讀現象。

 

事務的隔離級別

事務的隔離級別擁有四種:

1、Read Uncommitted(讀未提交):事務修改數據后即使未提交,其他事務也可以讀取到該事務修改后未被提交的數據,所以這個級別的隔離機制無法解決臟讀、不可重復讀、幻讀中的任何一種

2、Read Committed (讀已提交):能夠讀取到那些已經提交的數據,能夠防止臟讀,但是無法解決不可重復讀和幻讀的問題

3、Repeatable Read(重復讀):在數據讀取出來后對其加鎖,防止別人修改他,即讀取了一條數據,改事務不結束,別的事務就不能修改這條記錄,能夠解決臟讀、不可重復讀的問題,但是幻讀依舊解決不了

4、Serializable(串行化):最高級別的事務隔離級別,不管擁有多少事務,只有執行完一個完整的事務后才能執行下一個事務,這樣能夠避免臟讀、不可重復讀、幻讀的問題

 

事務的隔離級別設置的越高,事務對數據進行操作的行為就越安全,但是安全的代價是事務執行效率的降低,所以事務的隔離級別并不是設置的越高越好,實際開發中我們需要在安全性和執行效率之間做一個權重比

 

查看事務的隔離級別以及修改的命令

 查看mysql事務隔離級別命令

查看會話當前隔離級別:SELECT @@TX_ISOLATION;

查看系統當前隔離級別:SELECT @@GLOBAL.TX_ISOLATION;

修改會話當前的隔離級別:SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; (READ UNCOMMITTED || READ COMMITTED || REAPEATABLE READ)

修改系統當前的隔離級別:SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;(READ UNCOMMITTED || READ COMMITTED || REAPEATABLE READ)

 

注:作為入坑不久的小白,第一次寫博客,如有不對的地方,請指出,謝謝!

 

posted @ 2019-06-19 11:18 寄曇說 閱讀(...) 評論(...) 編輯 收藏
内部期期公开一波中特