數據庫的四大特性以及四個隔離級別和引起的問題

四大特性(ACID)

1.原子性(Atomicity)

  原子性是指事務包含的全部操做要麼所有成功,要麼所有失敗回滾。失敗回滾的操做事務,將不能對事務有任何影響。mysql

2. 一致性(Consistency)

  一致性是指事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態,也就是說一個事務執行以前和執行以後都必須處於一致性狀態。sql

  例如:A和B進行轉帳操做,A有200塊錢,B有300塊錢;當A轉了100塊錢給B以後,他們2我的的總額仍是500塊錢,不會改變。數據庫

3. 隔離性(Isolation)

  隔離性是指當多個用戶併發訪問數據庫時,好比同時訪問一張表數據庫每個用戶開啓的事務,不能被其餘事務所作的操做干擾(也就是事務之間的隔離),多個併發事務之間,應當相互隔離。
  例如同時有T1和T2兩個併發事務,從T1角度來看,T2要不在T1執行以前就已經結束,要麼在T1執行完成後纔開始。將多個事務隔離開,每一個事務都不能訪問到其餘事務操做過程當中的狀態;就比如上鎖操做,只有一個事務作完了,另一個事務才能執行。併發

4. 持久性(Durability)

  持久性是指事務的操做,一旦提交,對於數據庫中數據的改變是永久性的,即便數據庫發生故障也不能丟失已提交事務所完成的改變。oracle

事務的隔離級別

  事務的隔離級別從低到高分別是:讀未提交,讀已提交,可重複讀,串行化,這四個隔離級別能夠分別解決髒讀,不可重複讀,幻讀的問題。spa

先介紹一下不存在事務隔離級別的時候會出現的狀況

 

  很明顯的看出,旺財對A添加的20塊不知去向了,這就是「數據丟失」,對事務不加任何鎖(不存在事務隔離),就會致使這種問題。3d

讀未提交

   操做:寫數據的時候添加一個X鎖(排他鎖),也就是在寫數據的時候不容許其餘事務進行寫操做,可是讀不受限制,讀不加鎖blog

 

這樣就能夠解決了多我的一塊兒寫數據而致使了「數據丟失」的問題,可是會引起新的問題——髒讀。事務

髒讀:讀取了別人未提交的數據。ci

 

於是引入了另一個事務隔離級別——讀已提交

讀已提交

  操做:寫數據的時候加上X鎖(排他鎖),讀數據的時候添加S鎖(共享鎖),並且有約定:若是一個數據加了X鎖就無法加S鎖;同理若是加了S鎖就無法加X鎖,可是一個數據能夠同時存在多個S鎖(由於只是讀數據),而且規定S鎖讀取數據,一旦讀取完成就馬上釋放S鎖(無論後續是否還有不少其餘的操做,只要是讀取了S鎖的數據後,就馬上釋放S鎖)。

 

  這樣就解決了髒讀的問題,可是又有新的問題出現——不可重複讀。

不可重複讀:同一個事務對數據的屢次讀取的結果不一致

 

解決方法——引入隔離級別更高事務隔離:可重複讀

可重複讀

   操做:對S鎖進行修改,以前的S鎖是:讀取了數據以後就馬上釋放S鎖,如今修改是:在讀取數據的時候加上S鎖,可是要直到事務準備提交了才釋放該S鎖,X鎖仍是一致。

這樣就解決了不可重複讀的問題了,可是又有新的問題出現——幻讀。

例如:

有一次旺財對一個「學生表」進行操做,選取了年齡是18歲的全部行, 用X鎖鎖住, 而且作了修改。

改完之後旺財再次選擇全部年齡是18歲的行, 想作一個確認, 沒想到有一行居然沒有修改!

這是怎麼回事? 出了幻覺嗎?

原來就在旺財查詢並修改的的時候, 小強也對學生表進行操做, 他插入了一個新的行,其中的年齡也是18歲! 雖然兩我的的修改都沒有問題, 互不影響, 但從最終效果看, 仍是出了事。

碼農翻身注: 正是小強的操做, 讓旺財出現了「幻讀」)

解決幻讀的方式——串行化

串行化

  事務只能一件一件的進行,不能併發進行。

 

總結:

 

mysql默認的隔離級別是:可重複讀。

oracle中只支持2個隔離級別:讀已提交和串行化,默認是讀已提交。

 

擴展一些關於範式的的總結:

第一範式:一個單元格只存儲一個值。

第二範式:知足全部的屬性字段惟一依賴主鍵

第三範式:消除傳遞依賴,例如:訂單號----決定----->用戶id------決定------>用戶名;這個時候咱們就須要消除這種依賴傳遞;可是又時候也得兼顧查詢效率,高查詢率低修改率的字段能夠考慮違反第三範式。

  

參考:劉欣《碼農翻身》中的數據庫村的旺財和小強

相關文章
相關標籤/搜索