關係型資料庫事務的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; 設定系統當前隔離級別