理解資料庫事務隔離級別以及髒讀, 不可重複讀, 幻讀
資料庫事務的4個特性:
原子性(atomic): 都成功或者都失敗;
一致性(consistency):事務操作之後,資料庫所處的狀態和業務規則是一致的;比如a,b賬戶相互轉賬之後,總金額不變;
隔離性(isolation):操作中的事務不相互影響;
永續性(durability):事務提交後被持久化到資料庫.
髒讀,不可重複讀, 幻讀
幻讀phantom read:事務1讀取記錄時事務2增加了記錄並提交,事務1再次讀取時可以看到事務2新增的記錄;
不可重複讀unrepeatable read:事務1讀取記錄時,事務2更新了記錄並提交,事務1再次讀取時可以看到事務2修改後的記錄;
髒讀dirty read:
事務隔離級別描述:
READ UNCOMMITTED:幻讀,不可重複讀和髒讀均允許;
READ COMMITTED:允許幻讀和不可重複讀,但不允許髒讀;
REPEATABLE READ:允許幻讀,但不允許不可重複讀和髒讀;
SERIALIZABLE:幻讀,不可重複讀和髒讀都不允許;
ORACLE預設的是 READ COMMITTED。
如何感性理解這些“深奧”的術語?個人認為, 作為一個java程式設計師,這些字眼比較唬人。
首先, 隔離級別描述了事務被隔離的程度。可以簡單的想象一下, 一個人因為某種原因(比如國家安全)需要被隔離,則涉及安全的機密程度越高, 需要個隔離級別就越高,他與外界的溝通渠道就越少。
對於資料庫而言, 每個事務都要佔用一些資源,比如對錶/資料享有的操作許可權,事務的隔離級別描述了事務對資源享用的程度。
如果資料庫的隔離級別為REAE_UNCOMMITTED, 則其他執行緒可以看到未提交的資料, 因此就出現髒讀;
如果資料庫隔離級別設為READ_COMMITTED,即沒提交的資料別人是看不見的,就避免了髒讀;但是,正在讀取的資料只獲得了讀取鎖,讀完之後就解鎖,不管當前事務有沒有結束,這樣就容許其他事務修改本事務正在讀取的資料。導致不可重複讀。
REPEATABLE READ因為對正在操作的資料加鎖,並且只有等到事務結束才放開鎖, 則可以避免不可重複讀;
REPEATABLE READ
SERIALIZABLE因為獲得範圍鎖,且事務是一個接著一個序列執行,則保證了不會發生幻讀。
由此可見,隔離級別越高,受其他事物干擾越少,併發效能越差。
設定語法
Oracle:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|READ COMMITTED|READ UNCOMMITTED|REPEATABLE READ;
Sybase:
sql opreation at isolation read committed