事務隔離

维基百科,自由的百科全书
跳转至: 导航搜索

事務隔離(Isolation),指的是在數據庫系統中並發事務之間的可見性,以及如何相互影響的定義。事務隔離是ACID的四個特性(原子性、一致性、隔離性、持久性)之一。

目录

事務隔離級別 [编辑]

ANSI/ISOSQL標準中,定義了四個事務隔離級別,分別用於不同的場合。

可序列化 [编辑]

可序列化(SERIALIZABLE)最高的隔離級別。在此級別下,所有事務的完整性都被保留,這意味着所有的事務可以被序列化地執行。當只有兩個事務之前沒有任何衝突時,纔能並行地執行。

可重複讀取 [编辑]

可重複讀取(REPEATABLE READS)級別下,數據庫系統會在在整個事務期間保持讀寫鎖(read write lock),但相較於可序列化範圍鎖(range-locks)不會被管理,所以幻象讀取(phantom reads)可能會出現。

授權讀取 [编辑]

授權讀取(READ COMMITTED)級別下,數據庫系統在整個事務期間保持寫入鎖(write lock),但讀取鎖(read lock)會在SELECT執行後立即釋放,所以不可重複讀取(non-repeatable reads)可能會出現。

未授權讀取 [编辑]

未授權讀取(READ UNCOMMITTED)最低的隔離級別。這個級別允許出現骯髒讀取(dirty reads)

讀取現象 [编辑]

下列的示例解釋了幻象讀取(phantom reads)不可重複讀取(non-repeatable reads)骯髒讀取(dirty reads)。數據在下表中定義:

users
id name age
1 Joe 20
2 Jill 25

骯髒讀取 [编辑]

當一個事務試圖讀取另一個還未提交的事務正在修改的某一行數據時,骯髒讀取(dirty reads)就會發生。

下列示例中,事務2正在修改某行,但還沒有提交。事務1試圖讀取這一行。如果事務2回滾了(rolls back)變更,或者後面又進行了其他的修改,那麼事務1就獲得了骯髒(dirty)的數據。

事務1 事務2
/* Query 1 */
SELECT * FROM users WHERE id = 1;
/* Query 2 */
UPDATE users SET age = 21 WHERE id = 1;
/* No commit here */
/* Query 1 */
SELECT * FROM users WHERE id = 1;
ROLLBACK; /* lock-based DIRTY READ */

不可重複讀取 [编辑]

當一個事務正在執行的時候,對某一行兩次讀取的結果不一致,則稱發生了不可重複讀取(non-repeatable reads)

以下示例中事務1讀取了某行,之後事務2立刻修改了這一行並提交了結果,事務1再讀取這一行的時候,結果就不一致了。

事務1 事務2
/* Query 1 */
SELECT * FROM users WHERE id = 1;
/* Query 2 */
UPDATE users SET age = 21 WHERE id = 1;
COMMIT; /* in multiversion concurrency
   control, or lock-based READ COMMITTED */
/* Query 1 */
SELECT * FROM users WHERE id = 1;
COMMIT; /* lock-based REPEATABLE READ */

幻象讀取 [编辑]

幻象讀取(phantom reads)指的是兩次集合查詢之間返回了不一致的結果。不一致一般是由其他事务新增数据导致。以下示例展現了這一現象。

事務1 事務2
/* Query 1 */
SELECT * FROM users
WHERE age BETWEEN 10 AND 30;
/* Query 2 */
INSERT INTO users VALUES ( 3, 'Bob', 27 );
COMMIT;
/* Query 1 */
SELECT * FROM users
WHERE age BETWEEN 10 AND 30;

隔離級別、讀取現象與鎖 [编辑]

隔離級別與讀取現象 [编辑]

隔離級別 骯髒讀取 不可重複讀取 幻象讀取
未授權讀取 可能發生 可能發生 可能發生
授權讀取 - 可能發生 可能發生
可重複讀取 - - 可能發生
可序列化 - - -

隔離級別與鎖 [编辑]

为了解决上面的4种问题,就出现了4种隔离级别,不同的数据库默认使用不同的隔离级别 1.read uncommit 当事务A更新某条数据时,不容许其他事务来更新该数据,但可以读取。 2.read commit 当事务A更新某条数据时,不容许其他事务进行任何操作包括读取,但事务A读取时,其他事务可以进行读取、更新 3.read repeatable 当事务A更新数据时,不容许其他事务进行任何操作,但当事务A进行读取时,其他事务只能读取,不能更新。 4.serializable 最严格的隔离级别,事务必须依次进行。

整理成表格如下:

隔離級別 寫入鎖 讀取鎖 範圍鎖
READ UNCOMMITTED(允许读未提交数据) V - -
READ COMMITED(只能读已提交数据) V S -
REPEATABLE READ(事务内重复读同一块数据保持不变) V V -
SERIALIZABLE(事务逐个串行操作) V V V

"V" 排他锁。锁定将持续到事务结束。

"S" 共享锁。一般写锁都是排他的,否则连最低的事务隔离级别都无法保证,会出现更新丢失(Lost update)的情况。读锁有共享读锁和排他读锁之分,两者都要等待对应范围的写锁被释放后才能获取,以避免读到脏数据;区别是前者仅在读取完成后即释放,而无需等到事务结束,且支持同时被多个读操作持有(意即共享)。

樂觀鎖與多版本並發控制 [编辑]

在鎖定控制的數據庫系統中,死鎖(dead lock)指的是兩個以上的事務互相依賴等待,從而都被阻塞的現象。與多線程程序的設計不同,鎖定控制的數據庫中死鎖出現是很正常現象,而且是無法根本上避免的。當死鎖出現並且被數據庫系統檢測到時,所有死鎖的事務都會被駁回,用戶不得不根據需要進行重提交。然而死鎖不僅檢測代價是很高昂的,而且還會浪費大量資源,如果死鎖頻繁出現,會大大降低數據庫系統的並發性能。但我們不能爲了避免死鎖而降低隔離等級,而且有一點可以肯定的是,事務隔離級別越高,死鎖出現的概率就越大。

爲了提高性能,樂觀鎖(optimistic locking)機制被提出。與傳統的悲觀鎖(pessimistic locking)「先取鎖再訪問」的保守策略不同,樂觀鎖相信事物之間的數據競爭(data race)的概率是比較小的,因此盡可能直接做下去,直到提交的時候纔去鎖定。但如果直接簡單這麼做,還是有可能會遇到不可預期的結果,例如兩個事務都讀取了數據庫的某一行,經過修改以後寫回數據庫,這時就遇到了問題。一種可靠的樂觀鎖的實現是使用「多版本控制(multi-version control)」,即在每一行加一個version屬性。修改這一行時將version增加1,寫回數據庫要檢查當前的version值是否還是獲取時的那個值了。如果還是,說明期間沒有其他事務對其修改,直接提交即可,如果已經不是了,說明期間已經有別的事務修改了這一行,當前事務獲取的數據已經過期了,事務失敗。

PostgreSQLMySQLInnoDB引擎的實現中,多版本控制的樂觀鎖內置的(build-in),所以這個無需手動添加version字段。默認情況下,PostgreSQL/MySQL會盡可能使用樂觀鎖,除非遇到顯式的鎖定命令,如「select * from sometable for update」這樣的語句,纔會主動使用悲觀鎖

相關條目 [编辑]

外部鏈接 [编辑]

数据库管理系统(DBMS) (查看 · 讨论 · 编辑)

概念
数据库 · 数据模型 · 数据库存储结构英语Database storage structures · 关系 (数据库) · 关系模型 · 分布式数据库 · ACID ( 原子性 · 一致性 · 隔離性 · 持久性 ) · Null值
关系数据库 · 关系代数 · 关系演算 · 元组关系演算 · 域关系演算 · 数据库规范化 · 數據庫完整性 · 實體完整性 · 參照完整性 · 关系数据库管理系统 
主键 · 外键 · 代理键 · 超键 · 候选键 

数据库组件
触发器 · 视图 · 数据库表 · 指标 (数据库) · 事务日志英语Transaction log · 数据库事务 · 并发控制 · 乐观锁 · 悲观锁 · 数据库索引 
存储程序 · 資料庫分割

SQL
分类: 数据查询语言 (DQL) - 資料定義語言 (DDL) - 資料操縱語言 (DML) - 資料控制語言 (DCL)
指令:SELECT · INSERT · UPDATE · MERGE · DELETE · JOIN · UNION · CREATE · DROP · Begin work · COMMIT · ROLLBACK · TRUNCATE · ALTER
安全: SQL資料隱碼攻擊 · 參數化查詢

数据库管理系统的实施

实施类型
关系数据库 · 檔案型資料庫 · Deductive · 維度化資料庫 · 階層式 · 圖形資料庫 · 对象数据库 · 物件關聯式資料庫 · Temporal · XML資料庫

数据库产品
对象型 (对比) · 关系型 (对比)

数据库成分
数据查询语言 · 查詢最佳化器 · 查詢計畫 · 嵌入式SQL · ODBC · JDBC · OLE DB