數據庫隔離級別:是在在數據庫操作中,為了有效保證並發讀取數據的正確性提出的。
隔離級別越高,越能保證數據的完整性和一致性,但是對並發性能的影響也越大。對於多數應用程序,可以優先考慮把數據庫系統的隔離級別設為Read Committed。它能夠避免臟讀取,而且具有較好的並發性能。盡管它會導致不可重復讀、幻讀和第二類丟失更新這些並發問題,在可能出現這類問題的個別場合,可以由應用程序采用悲觀鎖或樂觀鎖來控制。
數據庫的幾種隔離級別:
- READ UNCOMMITTED(讀未提交數據):允許事務讀取未被其他事務提交的變更數據,會出現臟讀、不可重復讀和幻讀問題。
- READ COMMITTED(讀已提交數據):只允許事務讀取已經被其他事務提交的變更數據,可避免臟讀,仍會出現不可重復讀和幻讀問題。
- REPEATABLE READ(可重復讀):確保事務可以多次從一個字段中讀取相同的值,在此事務持續期間,禁止其他事務對此字段的更新,可以避免臟讀和不可重復讀,仍會出現幻讀問題。
- SERIALIZABLE(串行化):確保事務可以從一個表中讀取相同的行,在這個事務持續期間,禁止其他事務對該表執行插入、更新和刪除操作,可避免所有並發問題,但性能非常低。
Oracle支持兩種事務隔離級別: READ COMMITTED(默認事務隔離級別),SERIALIZABLE(序列化)
MySQL支持四種事務隔離級別,其中REPEATABLE READ(RR可重復讀)為默認事務隔離級別。
通過上面可以知道多事務同時運行,如果不采用以上四種隔離機制,可能會產生多個並發問題,其中包括臟讀、不可重復讀和幻讀,下面就解釋下這幾種並發問題:
存在兩個事務(A,B)同時運行
- 臟讀:事務A讀取了已經被事務B修改但還未提交的字段,由於事務B回滾,則事務A讀取的是臟數據。
- 不可重復讀:不可重復讀與臟讀邏輯類似。主要在於事務B在事務A第二次讀取時,跟新了數據。導致事務A前后兩次讀取的數據不一致。
- 幻讀:事務A第二次查詢時,讀到了事務B提交的數據。
- 不可重復讀和幻讀的區別: 不可重復讀是值不同,幻讀是數據條數不同。
在mysql中通過MVCC(快照讀)和next-key(當前讀)兩種模式解決幻讀問題。
舉例:https://www.cnblogs.com/liyus/p/10556563.html
數據庫事務的特性:原子性、一致性、隔離性、持久性:
- 原子性:事務的原子性指的是,事務中包含的程序作為數據庫的邏輯工作單位,它所做的對數據修改操作要么全部執行,要么完全不執行,這種特性稱為原子性。(簡單地說就是,幾個對於數據庫的操作要么全執行,要么全不執行,即同時成功起作用或同時失敗沒影響)
- 一致性:事務一致性值得是在一個事務執行之前和執行之后數據庫都必須處於一致性狀態(中途是否一致不用管),這種特性稱為一致性。(如果數據庫的狀態滿足所有的完整性約束,就說該數據庫是一致的。一致性處理數據庫中對所有語義的保護。如:客戶K1要向客戶K2轉賬,K1賬戶減少的金額就是K2賬戶增加的金額,在轉賬之前K1和K2賬戶的金額之和與轉賬之后K1和K2賬戶的金額之和是一樣的,在轉賬期間可能不滿足這種一致性,但事務前后是數據庫數據是一致的)
- 隔離性:隔離性指的是並發的事務是相互隔離的。(一個事務內部的操作及正在操作的數據必須封裝起來,不被其它企圖進行修改的事務看到)
- 持久性:持久性指當系統或介質發生故障時,確保已提交的更新不能丟失。(一個事務提交,DBMS保證它對數據庫中數據的改變應該是永久性的,可以經受任何系統故障,持久性通過數據庫備份和恢復來保證)
查詢mysql事務隔離級別的sql操作:
2.查看系統當前隔離級別 select @@global.tx_isolation;
3.設置當前會話隔離級別 set session transaction isolatin level repeatable read;
4.設置系統當前隔離級別 set global transaction isolation level repeatable read;