什麼是事務?
事務,即資料庫事務。是資料庫管理系統執行過程中的一個邏輯單位,由一個有限的資料庫操作序列構成。
通常,事務的正確執行會使資料庫從一種狀態轉換為另一種狀態。
事務的特性(ACID原則)
- 原子性(atomicity) 即不可分割性,事務要麼全執行、要麼全不執行。
- 一致性(consistency) 事務的執行使得資料庫從一種正確狀態轉換成另外一種正確狀態。
- 隔離性(isolation) 在事務正確提交之前,不允許把事務對該資料的改變提供給任何其他事務。
- 永續性(durability) 事務正確提交之後,其結果將永遠儲存在資料庫之中。
併發狀態下事務會產生的問題
併發狀態解釋為當事務A和事務B對同一資源進行操作時,可能會遇到很多的問題。
髒讀(針對未提交資料)
即事務A讀到了事務B還沒有提交的資料。如果事務A對資料進行了更新,但是事務A並沒有提交,但是事務B這個時候看到了事務A沒有提交的更新。當事務A進行了回滾,那麼剛剛事務B看到的資料就是髒資料。也就是髒讀。
例子:
A 給 B 轉了100萬,但是 A 還沒有提交,此時 B 查詢自己賬戶,多了100萬。然後 A 發現轉錯人了,回滾了事物。然後 B 100萬就沒了。在這個過程中 B 查到了沒有提交的資料(多出的100萬),這就是髒讀。
不可重複讀(在一個事務裡面讀取了兩次某個資料,讀出來的資料不一致,針對修改操作)
即同一事務在事務執行過程中對同一個資料進行了多次讀取,但是每一次讀取的資料結果都不相同。原因是在兩次讀取間隔,資料別其他人修改了,導致了統一事務兩次讀取結果不一致。
例子:
A 查詢銀行餘額為100萬,B 這個時候取走了50萬,此時餘額變成了50萬,A 再一次查詢餘額,變成了50萬。對 A 而言兩次結果不一致就是不可重複讀。
幻讀(在一個事務裡面的操作中發現了未被操作的資料,針對增刪操作)
即在事務 A 多次讀取資料集的過程中中,事務 B 對資料進行了新增操作或者刪除操作,導致事務 A 多次讀取的資料集不一致。
例子:
A 修改當前公司所有職員資訊的時候,B 向其中插入了一個新的職員,這個時候 A 提交的時候發現了一個自己沒有修改過的職員的資訊,對 A 而言就像是產生了幻覺。
事務的隔離級別
為了應對上面併發情況下出現的問題,事務的隔離級別就產生了。當事務的隔離級別越高的時候,上面的問題就會越少,但是效能消耗也會越大。所以在實際生產過程中,要根據需求去確定隔離級別。
四種隔離級別
READ_UNCOMMITTED
讀未提交,即能夠讀取到沒有被提交的資料,所以很明顯這個級別的隔離機制無法解決髒讀、不可重複讀、幻讀中的任何一種。
READ_COMMITED
已提交,即能夠讀到那些已經提交的資料,能夠防止髒讀,但是無法解決不可重複讀和幻讀的問題。
REPEATABLE_READ
重複讀取,即在資料讀出來之後加鎖,類似"select * from XXX for update",明確資料讀取出來就是為了更新用的,所以要加一把鎖,防止別人修改它。REPEATABLE_READ的意思也類似,讀取了一條資料,這個事務不結束,別的事務就不可以改這條記錄,這樣就解決了髒讀、不可重複讀的問題,但是幻讀的問題還是無法解決。
SERLALIZABLE
序列化,最高的事務隔離級別,不管多少事務,挨個執行完一個事務的所有子事務之後才可以執行另外一個事務裡面的所有子事務,這樣就解決了髒讀、不可重複讀和幻讀的問題了。