前幾日有一個獵頭公司的面試,其中問道我事務隔離這塊的知識點,猛一問真是想不起來啊,頓感羞愧啊,回來專門總結一下這方面的知識來夯實一下以前的知識體系,也提醒廣大園友們進步在於總結啊,好多不用的知識點,有時候有必要溫故知新啊。面試
簡介 數據庫
ACID,是指在可靠數據庫管理系統(DBMS)中,事務(transaction)所應該具備的四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability).這是可靠數據庫所應具有的幾個特性.併發
咱們經過SQL SERVER對數據庫進行管理,不可避免要實現多個進程訪問數據庫同一數據,或者修改同一數據。 這樣就不得不提到SQL Server利用加鎖和阻塞來保證事務之間不一樣等級的隔離性,從而實現事務的互不干擾的訪問和操做數據庫。性能
首先咱們要知道都有哪些干擾會影響數據的隔離性:spa
一、更新丟失(lost update):當系統容許兩個事務同時更新同一數據是,發生更新丟失。3d
二、髒讀(dirty read):當一個事務讀取另外一個事務還沒有提交的修改時,產生髒讀。blog
舉例說明什麼是髒讀:進程
經過以上三個圖不難發現,當事務1去插入一條數據,而後圖二去讀取被插入數據的表,此時事務1尚未commit結果查詢結果直接將內存中的髒數據讀取出來,再Read Uncommitted 這個級別下,會出現髒讀,一旦數據未提交或者未提交成功則讀取數據是髒讀錯誤數據。事務
三、非重複讀(nonrepeatableread):同一查詢在同一事務中屢次進行,因爲其餘提交事務所作的修改或刪除,每次返回不一樣的結果集,此時發生非重複讀。內存
舉例說明:
以上三圖能夠清楚表示出,在一個事務中,兩個查詢對同一個表,而再事務兩次查詢中發生了一次數據更新,致使事務中兩次查詢的結果不一樣。這就是所謂的nonrepeatableread。
四、幻像(phantom read):同一查詢在同一事務中屢次進行,因爲其餘提交事務所作的插入操做,每次返回不一樣的結果集,此時發生幻像讀。
在標準SQL規範中,定義了4個事務隔離級別,不一樣的隔離級別對事務的處理不一樣:
◆未受權讀取(Read Uncommitted):容許髒讀取,但不容許更新丟失。若是一個事務已經開始寫數據,則另一個事務則不容許同時進行寫操做,但容許其餘事務讀此行數據。該隔離級別能夠經過「排他寫鎖」實現。
◆受權讀取(Read Committed):容許不可重複讀取,但不容許髒讀取。這能夠經過「瞬間共享讀鎖」和「排他寫鎖」實現。讀取數據的事務容許其餘事務繼續訪問該行數據,可是未提交的寫事務將會禁止其餘事務訪問該行。
◆可重複讀取(Repeatable Read):禁止不可重複讀取和髒讀取,可是有時可能出現幻影數據。這能夠經過「共享讀鎖」和「排他寫鎖」實現。讀取數據的事務將會禁止寫事務(但容許讀事務),寫事務則禁止任何其餘事務。
◆序列化(Serializable):提供嚴格的事務隔離。它要求事務序列化執行,事務只能一個接着一個地執行,但不能併發執行。若是僅僅經過「行級鎖」是沒法實現事務序列化的,必須經過其餘機制保證新插入的數據不會被剛執行查詢操做的事務訪問到。
最後附上設置隔離級別的語法(總是記不清楚):
SET TRANSACTION ISOLATION LEVEL
{
READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SERIALIZABLE
}
總結
經過全篇的講述,咱們也能清晰的理順一條思路,隔離級別越高,越能保證數據的完整性和一致性,可是對併發性能的影響也越大。對於多數應用程序,能夠優先考慮把數據庫系統的隔離級別設爲Read Committed,它可以避免髒讀取,並且具備較好的併發性能。儘管它會致使不可重複讀、虛讀和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,能夠由應用程序採用悲觀鎖或樂觀鎖來控制。