概要
數據庫隔離級別是關系型數據庫保障事務生命周期過程中幾個層次的數據安全策略。
隔離級別越高,越能保證數據的完整性和一致性,但是對并發性能的影響也越大;而隔離級別越低,事務并發性越強,但同時會出現與業務情況相背的數據情況。如果系統壓力偏大而業務數據能支持較強的容錯情況,我們可以選擇相對較低的事務隔離級別,在個別應用場景可以由應用程序采用悲觀鎖或樂觀鎖來控制低級別事務隔離級別引出的數據安全情況;而數據一致性需求較強的應用場景,如果系統壓力并不大且在一個可控的壓力范圍之內,我們可以選擇較高的事務隔離級別支持,甚至可以選擇最高的串行執行的隔離級別Serializable。
事務完整性
事務完整性可以用ACID特性來衡量事務的質量,違反事務完整性的問題有3類:臟讀、不可重復讀和幻像讀。
ACID:原子性(atomicity),一致性(consistency),隔離性(isolation),持續性(durability)
原子性:事務是原子的,要不全部完成,要不全部失敗。
一致性:保證數據庫的一致性,事務執行之前是一致的,執行之后也是一致的。
隔離性:每個事務必須和其他事務產生的結果隔離開來。
持續性:事務的持續性指不管系統發生了什么故障,事務處理的結果都是永久的,數據庫產品必須保證,即使存放數據的驅動器融化了,也能將數據庫恢復到驅動器融化之前,即最后一個事務提交的瞬間狀態。
事務缺陷:臟讀、不可重復讀、幻像讀
1)臟讀
讀取了其它事務未提交的數據。
2)不可重復讀
對于單行數據來說。事務A兩次讀取的數據不一致,因為看到的是事務B提交前后的數據,自然不一致。
3)幻像讀
對于多行數據來說。事務A兩次讀取的行數不一致,因為在其過程中正巧事務B修改并提交了滿足事務A查詢條件的記錄。
幾種隔離級別
以JDBC中Connection的事務隔離級別定義來說明:
1)Read Uncommitted(TRANSACTION_READ_UNCOMMITTED)
事務A可以讀取到事務B未提交的數據,如果事務B發生異常回滾,事務A讀取到的將是臟數據。此事務隔離級別的應用場景中將出現臟讀、不可重復讀和幻像讀這幾種情況。
2)Read Committed(TRANSACTION_READ_COMMITTED)
事務A可以讀取到事務B已經提交的數據,不可讀取到事務B未提交的數據,避免了臟讀,但沒有避免不可重復讀和幻像讀。
3)Repeatable Read(TRANSACTION_REPEATABLE_READ)
可以回避臟讀、不可重復讀的情況,但無法避免幻像讀。
4)Serializable(TRANSACTION_SERIALIZABLE)
防止所有的事務缺陷,適用于絕對的事務完整性的要求比性能更為重要的情況,銀行帳務系統、高度競爭性的銷售數據庫,等等,可以選擇使用Serializable。
事務隔離級別查看及修改
1)DB2
默認:Read Committed
查看:
修改:a.DB2SET DB2_SQLROUTINE_PREPOPTS=RR|RS|CS|UR
b.db2 change isolation to UR
c.SELECT * FROM tablename WITH UR
(RR-Serializable、RS-Repeatable Read、CS-Read Committed、UR-Read Uncommitted)
2)Oracle
默認:Read Committed
查看:
修改:set transaction isolation level serializable(Oracle只有read committed 和 serializable)
3)Sybase
默認:Read Committed
查看:select @@isolation
修改:set transaction isolation level 0
(level 3-Serializable、level 2-Repeatable Read、level 1-Read Committed、level 0-Read Uncommitted)
4)Sql Server
默認:Read Committed
查看:
修改:set transaction isolation level read uncommitted
5)Mysql
默認:Repeatable Read
查看:select @@tx_isolation;
修改:set transaction isolation level read uncommitted;