1. 程式人生 > >關係型資料庫事務的ACID原則和四種隔離級別

關係型資料庫事務的ACID原則和四種隔離級別

一、事務的四大特性的介紹

1、A (Atomicity) 原子性

就是說事務裡的所有操作要麼全部做完,要麼都不做,事務成功的條件是事務裡的所有操作都成功,只要有一個操作失敗,整個事務就失敗,需要回滾。

舉例:銀行轉賬,從A賬戶轉10元至B賬戶,需要經過兩個步驟:

                    1)從A賬戶取10元;

                    2)存入10元至B賬戶。

         注意:這兩步要麼一起完成,要麼一起不完成,如果只完成第一步,第二步失敗,A賬號的錢會莫名其妙少了100元。

2、C (Consistency) 一致性

 就是說資料庫要一直處於一致的狀態,事務的執行不會改變資料庫原本的一致性約束。

   舉例:現有完整性約束a+b=100,如果一個事務改變了a,那麼必須得改變b,使得事務結束後依然滿足a+b=100,否則事務失敗。

3、I (Isolation) 獨立性

獨立性是指併發的事務之間不會互相影響,如果一個事務要訪問的資料正在被另外一個事務修改,只要另外一個事務未提交,它所訪問的資料就不受未提交事務的影響。

比如現有有個交易是從A賬戶轉10元至B賬戶,在這個交易還未完成的情況下,如果此時B查詢自己的賬戶,是看不到新增加的10元的。

4、D (Durability) 永續性

永續性是指一旦事務提交後,它所做的修改將會永久的儲存在資料庫上,即使出現宕機也不會丟失。

二、事務的四種隔離級別介紹


1、Read uncommitted(讀未提交)

           ①說明:一個事務可以讀取另一個未提交事務的資料。

           ②可能出現問題:讀髒資料。

           ③解決方法:Read committed  讀提交,能解決髒讀問題。

           ④舉例:小李爸爸給小李100元零花錢,該錢已經打到小李的賬號上了,但是事務沒有提交,小李爸爸讓小李檢視下錢收到沒,小李一看,哇,老爸出手真闊綽啊,給了我100元零花錢。當小李檢視完錢的數量後,小李爸爸馬上回滾了剛才沒有提交的事務,然後將數字改為10元提交了。(在此為小李心疼三秒。)

2、Read committed(讀已提交)

            ①說明:一個事務要等到另一個失誤提交之後才能區讀取資料。

            ②可能出現問題:出現不可重複讀(事務的兩次讀取到的資料大小不一樣)。

            ③解決方法:Repeatable read

            ④舉例:小李爸爸去超市購物,使用刷卡買單,第一次刷卡收費系統檢測到該卡中餘額足夠支付小李爸爸買的東西,但是搗蛋鬼小李,在這中間用小李媽媽的手機把小李爸爸卡里的錢都拿來買巧克力了,並且將訂單提交了,事務提交完了。於是,當刷卡收費系統第二次檢測小李爸爸卡得餘額時,發現卡里沒有錢。

3、Repeatable read(可重複讀)----------------針對update操作

           ①說明:開始讀取資料(事務開啟)時,不再允許修改操作。

           ②可能出現問題:幻讀

           ③解決方法:Serializable,但是大部分情況使用使用加鎖(樂觀鎖和悲觀鎖)讀來進行保證。

           ④舉例:小李爸爸檢視自己昨天的消費情況,發現昨天確實消費了100元(事務開啟),但是這時候,小李拿著他得手機給自己買了一條褲子,花了100元,也就是insert了一條心得消費記錄,並提交。當小李爸爸列印自己的消費情況的時候,突然多了發現自己花了100元,這就是幻讀。

4、Serializable(序列化)    

           ①說明:事務序列化順序執行。

           ②優點:可以避免髒讀、不可重複讀(針對update和delete)、幻讀(針對insert)

           ③缺點:但是該事務隔離級別下,效率低下,不建議使用

注意:①MySQL的預設隔離級別是Repeatable read(可重複讀)。   

           ②SQLServer、Oracle的預設隔離級別是READ COMMITTED(讀已提交)

  三、不同資料庫對隔離級別的操作

    1、MySQL

        1)select @@tx_isolation;           檢視當前會話隔離級別

        2)select @@global.tx_isolation;     檢視系統當前隔離級別

        3)set session transaction isolatin level read committed;    設定當前會話隔離級別

        4)set global transaction isolation level read committed;     設定系統當前隔離級別

    2、SQLServer

        1)dbcc useroptions  isolation level       檢視系統當前隔離級別

        2)set transaction isolation level Read UnCommitted; 設定系統當前隔離級別