數據庫之事務詳解

什麼是事務

事務是訪問數據庫的一個或多個操作的組合,事務執行完之後可以使數據庫從一種狀態變爲另外一種狀態。

事務的四個特性

1、原子性

原子性指的是事務中的操作要麼全部執行,要麼全部不執行。這意味着如果事務正確執行,則數據庫從一種狀態成功地變爲了另外一種狀態;如果事務中的某個操作未正確執行,則已正確執行的其他操作需要對數據庫進行回滾,使數據庫恢復到該事務執行之前的狀態。

2、一致性

一致性指的是使數據庫從一種狀態正確地變爲另外一種狀態,這裏的關鍵詞是“正確地”,換句話說是,一個事務執行之前和執行之後都必須處於一致性狀態。舉個栗子,如果A給B匯款100元,則一致性就代表着A賬戶減少了100元,B賬戶增加了100元,但是他們的賬戶總和不會改變。

3、隔離性

隔離性指的是各個事務之間的執行不能相互影響,比如兩個事務併發地對某個數據進行操作,則A事務在對該數據進行操作時,B事務不能對其操作。

4、持久性

持久性指的是事務一旦被提交了,該事務對數據庫的數據改變就是永久性的,即時這時數據庫系統遇到了故障,事務的處理結果也會保存下來。

併發中的事務引起的問題

在併發操作中,如果不考慮事務的隔離性,會引起一系列的問題,如髒讀、不可重複讀、幻讀等。

1、髒讀

髒讀是指一個事務在處理過程中,讀到了另一個未提交的事務中的數據。舉個栗子,A向B轉賬100元這個事務需要兩條SQL語句,首先給B的賬戶添加100元,A的賬戶減少100元,假如執行完第一條SQL語句後發生了阻塞,此時B對其賬戶進行查詢操作,發現其賬戶已經多出了100元,但是此時事務阻塞結束,執行第二條語句時,發生了問題,這時數據庫就需要回滾數據,返回事務執行之前的狀態,那麼B的賬戶會再減少100元,那麼之前B查詢到的多出100元的結果就是髒讀。

2、不可重複讀

不可重複讀是指在一個事務中讀取了兩次同一個數據,但是結果不一致,這是因爲這個事務兩次查詢操作之間的時候被另外一個事務修改了數據。舉個栗子,事務A進行了兩次查詢賬戶的操作,事務B對賬戶進行了修改操作,改爲減少100元,那麼在A事務第一次查詢賬戶後如果發生阻塞,B事務此時開啓並執行,那麼再執行A事務的第二次操作時,就會發現賬戶少了100元,這就是發生了不可重複讀。

不可重複讀與髒讀的區別是,髒讀是A事務讀取了B事務未提交的數據,不可重複讀是讀取了B已提交的數據。

3、幻讀

幻讀是指在一個事務的操作後發現了未被操作的數據。什麼意思呢,還是舉個栗子吧,比如A事務想把所有人的賬戶數據全部改爲100元,但此時事務B對該表進行了一個插入操作,增加了一個人Q和賬戶200元,也就是表增加了一行,那麼A事務執行完畢後,會發現有一個人的賬戶未被修改過,這就是發生了幻讀。

幻讀和不可重複讀都是讀取了另一個已經提交的事務,不可重複讀的重點在於update和delete,而幻讀的重點是insert。

事務隔離級別

事務隔離級別是指的是事務四個特性之一的隔離性設置的不同級別,事務的隔離級別越高,由於併發導致的問題就會越少,但同時性能消耗也就更高。如果在兩者之間做一個衡量的話,可以對不同的數據選擇不同的隔離級別,MySQL支持四種隔離級別,默認爲可重複讀級別。

1、讀未提交(READ_UNCOMMITTED)

可以讀到沒有被提交的數據,隔離的最低級別,不能防止髒讀、不可重複讀、幻讀。

2、讀已提交(READ_COMMITED)

讀已提交是爲了解決髒讀的問題,它可以保證讀不到未被提交的數據,這樣的話就防止了髒讀。

3、可重複讀(REPEATABLE_READ)

重複讀是爲了解決不可重複讀的問題,將要查詢的數據加鎖,這樣其他事務就不會再對這些數據進行修改或刪除操作,就可以實現可重複讀了。但是這種對數據加鎖的方式沒辦法對其他事務的插入操作有效,所以不能防止幻讀。

4、串行化(SERLALIZABLE)

這個數據庫隔離的最高級別,可以避免髒讀、不可重複讀、幻讀,但這個級別的隔離也會降低數據庫的增刪改查性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章