什么是事務:
多條sql語句,要么全部成功,要么全部失敗。
事務的特性:
1:原子性(Atomic):
組成一個事務的多個數據庫操作是一個不可分割的原子單元,只有所有操作都成功,整個事務才會提交。任何一個操作失敗,已經執行的任何操作都必須撤銷,讓數據庫返回初始狀態
2:一致性(Consistency):
事務操作成功后,數據庫所處的狀態和它的業務規則是一致的。即數據不會被破壞。如A轉賬100元給B,不管操作是否成功,A和B的賬戶總額是不變的
3:隔離性(Isolation):
在并發數據操作時,不同的事務擁有各自的數據空間,它們的操作不會對彼此產生干擾
4:持久性(Durabiliy):
一旦事務提交成功,事務中的所有操作都必須持久化到數據庫中
簡稱ACID
并發事務帶來哪些問題
在典型的應用程序中,多個事務并發運行,經常會操作相同的數據來完成各自的任務(多個用戶對
同一數據進行操作)。并發雖然是必須的,但可能會導致以下的問題。
1:臟讀(Dirty read): 當一個事務正在訪問數據并且對數據進行了修改,而這種修改還沒有提
交到數據庫中,這時另外一個事務也訪問了這個數據,然后使用了這個數據。因為這個數據是
還沒有提交的數據,那么另外一個事務讀到的這個數據是“臟數據”,依據“臟數據”所做的操作可
能是不正確的。
2:丟失修改(Lost to modify): 指在一個事務讀取一個數據時,另外一個事務也訪問了該數
據,那么在第一個事務中修改了這個數據后,第二個事務也修改了這個數據。這樣第一個事務
內的修改結果就被丟失,因此稱為丟失修改。 例如:事務1讀取某表中的數據A=20,事務2也
讀取A=20,事務1修改A=A-1,事務2也修改A=A-1,最終結果A=19,事務1的修改被丟失。
3:不可重復讀(Unrepeatableread): 指在一個事務內多次讀同一數據。在這個事務還沒有結
束時,另一個事務也訪問該數據。那么,在第一個事務中的兩次讀數據之間,由于第二個事務
的修改導致第一個事務兩次讀取的數據可能不太一樣。這就發生了在一個事務內兩次讀到的數
據是不一樣的情況,因此稱為不可重復讀。
4:幻讀(Phantom read): 幻讀與不可重復讀類似。它發生在一個事務(T1)讀取了幾行數
據,接著另一個并發事務(T2)插入了一些數據時。在隨后的查詢中,第一個事務(T1)就會
發現多了一些原本不存在的記錄,就好像發生了幻覺一樣,所以稱為幻讀。
不可重復讀和幻讀區別:
不可重復讀的重點是修改比如多次讀取一條記錄發現其中某些列的值被修改,幻讀的重點在于新增
或者刪除比如多次讀取一條記錄發現記錄增多或減少了。
事務隔離級別 以及 MySQL的默認隔離級別
SQL 標準定義了四個隔離級別:
1:READ-UNCOMMITTED(讀取未提交): 最低的隔離級別,允許讀取尚未提交的數據變更,可能會導致臟讀、幻讀或不可重復讀。
2:READ-COMMITTED(讀取已提交): 允許讀取并發事務已經提交的數據,可以阻止臟讀,但是幻讀或不可重復讀仍有可能發生。
3:REPEATABLE-READ(可重復讀): 對同一字段的多次讀取結果都是一致的,除非數據是被本身事務自己所修改,可以阻止臟讀和不可重復讀,但幻讀仍有可能發生。
4:SERIALIZABLE(可串行化): 最高的隔離級別,完全服從ACID的隔離級別。所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀。
MySQL InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-READ(可重讀)。
這里需要注意的是:與 SQL 標準不同的地方在于 InnoDB 存儲引擎在 REPEATABLE-READ(可重
讀) 事務隔離級別下使用的是Next-Key Lock 鎖算法,因此可以避免幻讀的產生,這與其他數據庫
系統(如 SQL Server) 是不同的。所以說InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-
READ(可重讀) 已經可以完全保證事務的隔離性要求,即達到了 SQL標準的 SERIALIZABLE(可串行化) 隔離級別。因為隔離級別越低,事務請求的鎖越少,所以大部分數據庫系統的隔離級別都是READ-COMMITTED(讀取提交內容) ,但是你要知道的是InnoDB 存儲引擎默認使用REPEAaTABLE-READ(可重讀) 并不會有任何性能損失。InnoDB 存儲引擎在 分布式事務 的情況下一般會用到 SERIALIZABLE(可串行化) 隔離級別。