事務詳解

一、事務概述
  二、事務的特性
  三、事務的隔離問題


一、事務概述
  事務很好理解,就是要做的事情,而這件事情是由一系列的動作完成,這些動作要麼全部完成,要麼全部不起作用。也就是說如果一個動作沒有完成,其他所有的動作都將回到初始狀態。這就是事務,在操作數據時經常會用到事務。

  可能說的比較抽象,如果大家還不理解,那麼我就給大家舉個生活中最常見的例子。比如說轉賬這件事情,它是由付款和收款兩個動作組成,假如要轉賬100元,那麼付款這個動作就要將賬戶上的錢減少100元,而收款這個動作就要將賬戶上的錢增加100元,如果付款這個動作失敗,那麼收款這個動作自然也就不能成功。

  這樣說大家應該比較容易理解事務這個概念,當然事務中也有很多細節,接下來我就爲大家一一解惑。


二、事務的特性
  一個事務都應該具有以下四個特性ACID(原子性、一致性、隔離性、持續性),下面就爲大家一一解答。

1、原子性(Atomicity)
  事務包含的所有動作要麼全部成功,要麼全部失敗回滾(回滾的意思是回到最初的狀態,或滾到指定的狀態)。比如 用戶A 要轉給 用戶B 100元,那麼 用戶A 的賬戶 -100元,用戶B 的賬戶 +100元,如果 用戶A 的賬戶沒有減少100元,那麼 用戶B 的賬戶也不會增加100元,這就是事務的原子性。

2、一致性(Consistency)
  指事務前後的數據必須保持一致。用戶A 和 用戶B 的錢一共加起來是1000元,那麼不管A和B之間如何轉賬或轉幾次帳,他們倆的錢加起來還是1000元,總的數據是不能夠改變的,前後要保存一致,這就是事務的一致性。

3、隔離性(Isolation)
  一個事務的執行,不受其他事務的干擾,即併發執行的事務之間互不干擾。多個事務同時對同一組數據進行處理時,如果將這些事務進行隔離,那就一個事務處理完下一個事務才能開始處理,也就是說在同一時間內只能有一個事務來處理數據。比如說 用戶A 和 用戶B 同時給 用戶C 轉賬,這是兩個事務(用戶A 轉給 用戶C,用戶B 轉給 用戶C),因爲他們都對 用戶C 的賬戶作處理,所以要將這兩個事務隔離開。在事務處理的時候,必須一個事務處理完下一個事務才能開始處理,A先給C轉,或者B先給C轉,它們是不能同時進行的。


4、持續性(Durability)
  指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,即使數據庫發生故障也不應該對其有任何影響。用戶A 和 用戶B 之間的轉賬操作成功後,用戶A 和 用戶B 的賬戶上的錢就會發生永久的改變。


三、事務的隔離問題
  在事務的併發操作中,也就是多個事務同時對同一組數據進行操作時,可能會出現髒讀、不可重複讀、幻讀這三個問題,下面我們就一一來爲大家講解這三個問題。

1、髒讀
  一個事務讀到另一個事務沒有提交的數據。事務A修改了一個數據,但未提交,事務B讀到了事務A未提交的更新結果,事務B讀到的就是髒數據。

事例: 老闆要給程序員發工資,程序員的工資是3.6萬/月。但是發工資時老闆不小心按錯了數字,按成3.9萬/月,該錢已經打到程序員的戶口,但是事務還沒有提交,就在這時,程序員去查看自己這個月的工資,發現比往常多了3千元,以爲漲工資了非常高興。但是老闆及時發現了不對,馬上回滾差點就提交了的事務,將數字改成3.6萬再提交。

分析: 實際程序員這個月的工資還是3.6萬,但是程序員看到的是3.9萬。他看到的是老闆還沒提交事務時的數據。這就是髒讀,也就是看到了髒的數據。

2、不可重複讀
  一個事務讀到另一個事務修改後並提交的數據(update)。在同一個事務中,對於同一組數據讀取到的結果不一致。比如,事務B 在 事務A 提交前讀到的結果,和在 事務A 提交後讀到的結果可能不同。不可重複讀出現的原因就是由於事務併發修改記錄而導致的。

事例: 程序員拿着信用卡去享受生活(卡里當然是只有3.6萬),當他買單時(程序員事務開啓),收費系統事先檢測到他的卡里有3.6萬,就在這個時候!!程序員的妻子要把錢全部轉出充當家用,並提交。當收費系統準備扣款時,再檢測卡里的金額,發現已經沒錢了(第二次檢測金額當然要等待妻子轉出金額事務並提交完)。程序員就會很鬱悶,明明卡里是有錢的…

分析: 在這個事例中,涉及到了兩個事務(程序員事務和妻子事務),當程序員事務開啓時,收費系統讀取程序員卡里錢的操作還沒完成,此時妻子這個事務就將卡里的錢進行了轉賬,即對數據進行了修改,導致收費系統兩次讀取到的數據不一樣。出現了一個事務範圍內兩個相同的查詢卻返回了不同數據,這就是不可重複讀,這是由於數據更新導致的,不能重複讀取相同的數據。

事務的不可重複讀
3、虛讀(幻讀)
  一個事務讀到另一個事務新增加並提交的數據(insert)。在同一個事務中,對於同一組數據讀取到的結果不一致。比如,事務A 新增了一條記錄,事務B 在 事務A 提交前後各執行了一次查詢操作,發現後一次比前一次多了一條記錄。幻讀出現的原因就是由於事務併發新增記錄而導致的。

事例: 程序員某一天去消費,花了2千元,然後他的妻子去查看他今天的消費記錄(妻子事務開啓),看到確實是花了2千元,就在這個時候,程序員花了1萬買了一部電腦,即新增INSERT了一條消費記錄,並提交。當妻子打印程序員的消費記錄清單時(妻子事務提交),發現有兩條記錄,共花了1.2萬元,似乎出現了幻覺,這就是幻讀。

分析: 在這個事例中,事務B讀取了數據,接着另一個事務A插入了一條數據。在隨後的查詢中,事務B就會發現多了一條原本不存在的記錄,就好像發生了幻覺一樣,這是由於數據新增導致的。

事務的幻讀
注: 如果大家對 不可重複讀 和 幻讀 還是不太理解,接下來我們就看一下它們之間的區別。

不可重複讀和幻讀的區別
  不可重複讀的重點是修改數據,幻讀的重點是新增或者刪除記錄。

  不可重複讀,改變的是數據,數據記錄總條數並沒有發生改變;

  幻讀,改變的是數據記錄總條數,原來數據的值,沒有發生改變,只是新增了記錄條數。

疑問:
  大家可能會有這樣的疑問,幻讀不是因爲第二次讀到的結果和第一次讀到的結果不一樣而產生幻覺,所以叫幻讀嘛?好像不可重複讀也是這樣的,那爲什麼不可重複讀不叫幻讀呢?那是因爲大家可能忽略了一個細節,不可重複讀改變的是同一條數據,而幻讀改變的是數據的條數。第一次讀到一條,第二次卻讀到了兩條,好像產生了幻覺一樣,所以叫幻讀;而不可重複讀是第一次讀到這個數據的值和第二次讀到這個數據的值不一樣,也就是相同的數據不能重複讀兩次,否則會出錯,所以它叫做不可重複讀。

發佈了26 篇原創文章 · 獲贊 56 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章