淺談資料庫事務

Java學習錄發表於2019-03-22
事務的四大特性(ACID)
原子性

原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗。
例小王要向小李轉賬200元。則賬要麼轉賬成功小王賬戶減200元,小李賬戶加200元,要麼執行失敗,兩者賬戶都不動。

一致性

一致性是指事務執行之前和執行之後都必須處於一致性狀態。

假設轉賬前小王和小李的餘額之和是2000元,那麼不管他們之間進行了多少次轉賬,他們的餘額之和肯定還是2000元。

隔離性

隔離性是當多個事務併發運算元據庫時,不能被其他事務的操作所干擾

例小王銀行卡只有200元了,他要向小李轉賬200元時銀行方面進行銀行卡的年費扣除則這兩個操作必定不可能都成功。

永續性

永續性是指一個事務一旦提交,那麼對資料庫中的資料的改變就是永久性的。

當小王和小李之間進行一次轉賬時,這筆轉賬記錄便永久的儲存在資料庫裡.

併發事務存在的問題

上方提到了資料庫事務的隔離性,先看一下如果事務之間不進行隔離的話可能出現什麼問題

髒讀

髒讀是指在一個事務處理過程裡讀取了另一個未提交的事務中的資料。
  當一個事務正在多次修改某個資料,而在這個事務中這多次的修改都還未提交,這時一個併發的事務來訪問該資料,就會造成兩個事務得到的資料不一致。同上方的例子:小王向小李轉賬200元,對應SQL命令如下

12複製程式碼
update account set balance=balance+200 where name=’小李’; update account set balance=balance-200 where name=’小王’;複製程式碼

當只執行第一條SQL時,小李查詢餘額發現確實錢已到賬(此時即發生了髒讀),而之後如果該事務不提交或者出現異常,則所有操作都將回滾,那麼小李再次檢視賬戶時就會發現錢其實並沒有到賬。

不可重複讀

例如事務T1在讀取某一資料,而事務T2立馬修改了這個資料並且提交事務給資料庫,事務T1再次讀取該資料就得到了不同的結果,這個時候就發生了不可重複讀。

幻讀

例如事務T1對一個表中所有的行的某個資料項做了從“1”修改為“2”的操作,這時事務T2又對這個表中插入了一行資料項,而這個資料項的數值還是為“1”並且提交給資料庫。而操作事務T1的使用者如果再檢視剛剛修改的資料,會發現還有一行沒有修改,其實這行是從事務T2中新增的,就好像產生幻覺一樣,這就是發生了幻讀。

幻讀和不可重複讀都是讀取了另一條已經提交的事務,所不同的是不可重複讀查詢的是同一個資料項,而幻讀針對的是一批資料。

事務的隔離級別

Read uncommitted (讀未提交)最低階別,任何情況都無法保證。
Read committed (讀已提交):可避免髒讀的發生。
Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。
Serializable (序列化):可避免髒讀、不可重複讀、幻讀的發生。
注意

上方隔離級別從低到高,隔離級別越高效率越低。
在MySQL資料庫中,支援上面四種隔離級別,預設為Repeatable read
在Oracle資料庫中,只支援Serializable和Read committed ,預設為Read committed級別

淺談資料庫事務


相關文章