事物及事物隔離級別

2021-07-25 18:54:22 字數 2687 閱讀 6640

什麼是事物

事物是訪問資料庫的乙個操作序列,資料庫應用系統通過事物集來完成對資料庫的訪問。事物的正確執行使得資料庫從一種狀態轉換為另一種狀態。

事物必須服從iso/iec所制定的acid原則。acid是原子性(atomicity)、一致性(consistency)、隔離性(isolation)、永續性(durability)的縮寫,這四種狀態的意思是:

1、原子性

即不可分割,事物要麼全部被執行,要麼全部不執行。如果事物的所有子事物全部提交成功,則所有的資料庫操作被提交,資料庫狀態發生變化;如果有子事物失敗,則其他子事物的資料庫操作被回滾,即資料庫回到事物執行前的狀態,不會發生狀態轉換

2、一致性

事物的執行使得資料庫從一種正確狀態轉換成另外一種正確狀態

3、隔離性

在事物正確提交之前,不允許把事物對該資料的改變提供給任何其他事物,即在事物正確提交之前,它可能的結果不應該顯示給其他事物

4、永續性

事物正確提交之後,其結果將永遠儲存在資料庫之中,即使在事物提交之後有了其他故障,事物的處理結果也會得到儲存

事物的作用

事物管理對於企業級應用而言至關重要,它保證了使用者的每一次操作都是可靠的,即便出現了異常的訪問情況,也不至於破壞後台資料的完整性。就像銀行的自動提款機atm,通常atm都可以正常為客戶服務,但是也難免遇到操作過程中及其突然出故障的情況,此時,事物就必須確保出故障前對賬戶的操作不生效,就像使用者剛才完全沒有使用過atm機一樣,以保證使用者和銀行的利益都不受損失。

併發下事物會產生的問題

舉個例子,事物a和事物b操縱的是同乙個資源,事物a有若干個子事物,事物b也有若干個子事物,事物a和事物b在高併發的情況下,會出現各種各樣的問題。"各種各樣的問題",總結一下主要就是五種:第一類丟失更新、第二類丟失更新、髒讀、不可重複讀、幻讀。五種之中,第一類丟失更新、第二類丟失更新不重要,不講了,講一下髒讀、不可重複讀和幻讀。

1、髒讀

所謂髒讀,就是指事物a讀到了事物b還沒有提交的資料

,比如銀行取錢,事物a開啟事物,此時切換到事物b,事物b開啟事物-->取走100元,此時切換回事物a,事物a讀取的肯定是資料庫裡面的原始資料,因為事物b取走了100塊錢,並沒有提交,資料庫裡面的賬務餘額肯定還是原始餘額,這就是髒讀。

2、不可重複讀

所謂不可重複讀,就是指在乙個事物裡面讀取了兩次某個資料,讀出來的資料不一致

。還是以銀行取錢為例,事物a開啟事物-->查出銀行卡餘額為1000元,此時切換到事物b事物b開啟事物-->事物b取走100元-->提交,資料庫裡面餘額變為900元,此時切換回事物a,事物a再查一次查出賬戶餘額為900元,這樣對事物a而言,在同乙個事物內兩次讀取賬戶餘額資料不一致,這就是不可重複讀。

3、幻讀

所謂幻讀,就是指在乙個事物裡面的操作中發現了未被操作的資料

。比如學生資訊,事物a開啟事物-->修改所有學生當天簽到狀況為false,此時切換到事物b,事物b開啟事物-->事物b插入了一條學生資料,此時切換回事物a,事物a提交的時候發現了一條自己沒有修改過的資料,這就是幻讀,就好像發生了幻覺一樣。幻讀出現的前提是併發的事物中有事物發生了插入、刪除操作。

事物隔離級別

事物隔離級別,就是為了解決上面幾種問題而誕生的。為什麼要有事物隔離級別,因為事物隔離級別越高,在併發下會產生的問題就越少,但同時付出的效能消耗也將越大,因此很多時候必須在併發性和效能之間做乙個權衡

。所以設立了幾種事物隔離級別,以便讓不同的專案可以根據自己專案的併發情況選擇合適的事物隔離級別,對於在事物隔離級別之外會產生的併發問題,在**中做補償。

事物隔離級別有4種,但是像spring會提供給使用者5種,來看一下:

1、default

預設隔離級別,每種資料庫支援的事物隔離級別不一樣,如果spring配置事物時將isolation設定為這個值的話,那麼將使用底層資料庫的預設事物隔離級別。順便說一句,如果使用的mysql,可以使用"select @@tx_isolation

"來檢視預設的事物隔離級別

2、read_uncommitted

讀未提交,即能夠讀取到沒有被提交的資料,所以很明顯這個級別的隔離機制無法解決髒讀、不可重複讀、幻讀中的任何一種,因此很少使用

3、read_commited

讀已提交,即能夠讀到那些已經提交的資料,自然能夠防止髒讀,但是無法限制不可重複讀和幻讀

4、repeatable_read

重複讀取,即在資料讀出來之後加鎖,類似"select * from *** for update",明確資料讀取出來就是為了更新用的,所以要加一把鎖,防止別人修改它。repeatable_read的意思也類似,讀取了一條資料,這個事物不結束,別的事物就不可以改這條記錄,這樣就解決了髒讀、不可重複讀的問題,但是幻讀的問題還是無法解決

5、serlalizable

序列化,最高的事物隔離級別,不管多少事物,挨個執行完乙個事物的所有子事物之後才可以執行另外乙個事物裡面的所有子事物,這樣就解決了髒讀、不可重複讀和幻讀的問題了

網上專門有圖用**的形式列出了事物隔離級別解決的併發問題:

再必須強調一遍,不是事物隔離級別設定得越高越好,事物隔離級別設定得越高,意味著勢必要花手段去加鎖用以保證事物的正確性,那麼效率就要降低,因此實際開發中往往要在效率和併發正確性之間做乙個取捨,一般情況下會設定為read_commited,此時避免了髒讀,併發性也還不錯,之後再通過一些別的手段去解決不可重複讀和幻讀的問題就好了。

事物隔離級別

自然也是支援四種事務隔離級別的 read uncommitted,read commit,repeatable read serializable,下面就分別最四種隔離級別在實現的鎖機制做乙個簡介 serializable 1 這種隔離級別對資料的要求最為嚴格,自然也是效能最差的一種隔離級別。在所有...

事物隔離級別

隔離級別從松到緊 讀未提交,讀提交 重複讀,序列化。讀未提交 可能會出現髒讀的情況 例子 你去買5個包子。人多。店員拿的急多方乙個,袋子裡有6個,這個時候,你眼睛一瞟。心裡美滋滋。付錢的時候老闆檢查了一下,發現多了乙個,就拿走了乙個,然後你付錢走人 提交事務 這時候你就發現實際上袋子裡只有5個,但是...

事物隔離級別

在分布式的系統中,通常會有多個執行緒連線到資料庫中同時對乙個表進行操作 這裡的同時並不表示同乙個時間點,而是同時競爭cpu的資源,至於如何排程,就要看執行緒和作業系統如何進行排程了 這種情況下如果會話的事物設定不當,就會導致資料混亂,常常會出現以下三種情況 假設現在系統中有兩個會話a和b,同時對錶t...