1. 程式人生 > >鎖與隔離級別的關係

鎖與隔離級別的關係

遺留的一個.net專案,偶爾會出現一些比較詭異的問題,最近騰出功夫經過排查發現是由死鎖引起,下面是一張利用SQL Server Profiler追蹤到的死鎖狀況圖:


看到這張圖,說實話真是醉了,一個業務上還不算複雜的系統出現這麼複雜的死鎖挺罕見的,引起此問題的原因很簡單,就是該系統將90%的業務寫在了儲存過程,幾乎每一步操作都需要反覆的操作表來完成,結果導致偌大的伺服器記憶體利用率永遠在20%以下,CPU瞬時壓力巨大,沒有日誌,查詢bug也變得異常艱難,由於這種架構設計問題,從業務角度來修改似乎是不可能了,只能找一些臨時湊合的解決方案,比如修改隔離級別,死鎖超時時間等,關於這種由儲存過程構成的架構方案不想多說,想必很多架構設計人員不會去這麼設計,藉此想寫點關於資料庫事務隔離級別、鎖的基礎內容,本文就以微軟的

SqlServer資料庫為主。

造成死鎖的必要條件,是在併發環境下,兩個(或多個)程序對同一個資源競爭造成的,如上圖,橢圓表示程序,矩形表示資源,可以看出是多個程序均佔有Batch這張表造成了死鎖,解決此問題必須先要搞清楚為什麼會有鎖以及鎖的基本知識。

在實際業務處理中,需要很多步動作連貫完成,比如最經典的銀行轉賬,AB100元,必須要保證先從A賬戶減去100,然後在B賬戶加100,這個動作是不能間斷的,從程式角度看,為了保證這個動作完成,誕生了事務,事務有四個特性ACID,但事務僅僅只是一個概念,他不是具體的技術手段,那需要具體怎麼做才能保證事務ACID四個特性呢?關係型資料庫一般通過事務日誌和鎖的手段實現,事務日誌保證了原子性、一致性,事務日誌是由資料庫自行完成,因此一般開發人員接觸不到事務日誌,大概原理,就是在進行一切實際資料操作之前,都先寫好日誌,如果資料庫發生意外(比如斷電)後,及時可以通過日誌來自行恢復。鎖則保證了隔離性,保證多個事務能夠按照序列化的方式請求同一資料。

但現實世界是,很多操作需要並行,簡單粗暴的將所有操作(增刪改查)通過鎖來序列化執行必然行不通,因此需要更精細化來鎖定資源,從兩個方面入手,第一,針對鎖下手,增加鎖的型別:共享鎖(S)、獨佔鎖(X),還有一個特殊的更新鎖(U),還有幾乎不接觸的意向鎖、架構鎖等,針對每個鎖的解釋請參見《鎖模式》,他們之間是否相容的情況請看《鎖相容性》;第二,針對鎖資源範圍(鎖粒度),共有11個粒度,針對每個粒度的說明,MSDN有更詳盡的資料,這裡就不再貼上,附上鍊接:《鎖粒度和層次》。至於平時我們經常看到的樂觀鎖和悲觀鎖,可以參考Hibernate中的相關內容,文尾附了幾篇文章,可供參考。

一般來說,實際開發中,直接操作資料庫中各種鎖的機率相對比較少,更多的是利用資料庫提供的四個隔離級別,未提交讀、已提交讀、可重複讀、可序列化,還有一個特殊的基於行版本的已提交讀隔離級別,把它也可以歸到已提交讀內,基於行版本的隔離級別就是樂觀鎖的處理方式。那隔離級別和鎖是什麼關係?通俗來說,隔離級別是鎖的一個整體打包解決方案,我的理解是隔離封裝了鎖。針對這四種隔離,他們有各自的優點和缺點,如下表:

隔離級別

髒讀

丟失更新

不可重複讀

幻讀

未提交讀:Read Uncommited

已提交讀:Read commited

可重複讀:Repeatable Read

可序列讀:Serializable

從表來看,隔離級別從上到下依次增加,級別越低,引起的問題也就比較多,比如髒讀、丟失更新等,但等級越高,也就意味著需要管理更多的鎖,無法並行處理,效能方面又受損,因此,我們在設計系統時,只需要根據業務需求選擇一種當下適合的隔離級別。一種隔離級別,就有一套利用鎖的方案,如此設計,目的就是為了平衡效能和功能。

如何選擇一種合適的隔離級別,首選需要了解髒讀、丟失更新、不可重複讀和幻讀的引發的問題,有篇文章舉得例子不錯,移步:《事務之間的相互影響》,看完這篇文章中的例子,大多數人基本就明白了,下面是用自己語言總結的:

髒讀:事務A讀到事務B尚未提交的修改(updateInsertDelete)記錄後,事務B回滾了,事務A讀取到的就是不存在的資料;

不可重複讀:事務A第一次讀取後,事務B進行了修改(DeleteUpdate),再當事務A讀取時,發現數據在一個事務中前後不一;

幻讀:和不可重複讀類似,但幻讀針對Insert操作,當事務A第一讀取是表內有10行資料,此時事務B插入(Insert)了一條,當事務A再次讀取時發現變成了11行,造成幻覺;

丟失更新:事務A和事務B拿到同一份資料1A1的基礎上加1變成2後,此時B也在1的基礎上加2變成3,由於B提交晚,因此最終資料變成了3,覆蓋了事務A的操作,稱為丟失更新;

下面是從網路搜尋到到一張關於隔離級別和鎖關係的動態圖(上傳後居然不動了,對CSDN已經無力吐槽了-_-!):

http://static.oschina.net/uploads/img/201207/09074335_5YM8.gif

最後附上一些寫的比較好的文章:

相關推薦

隔離級別關係

遺留的一個.net專案,偶爾會出現一些比較詭異的問題,最近騰出功夫經過排查發現是由死鎖引起,下面是一張利用SQL Server Profiler追蹤到的死鎖狀況圖: 看到這張圖,說實話真是醉了,一個業務上還不算複雜的系統出現這麼複雜的死鎖挺罕見的,引起此問題的原因很簡單,就是該系統將90%的業務寫在了

事務隔離級別筆記

講解 三種 span http ont nbsp 隔離 server bsp SQL Server 2008 R2 事務與隔離級別實例講解 筆記 1、事務是數據庫的工作單元,可視為一個原子操作,要麽成功,要麽什麽也不曾發生   事務操作的三種命令:     a、     事

事務隔離級別------《Designing Data-Intensive Applications》讀書筆記10

串行化 clas block atomic 硬件故障 nsis 特性 筆記 額外 和數據庫打交道的程序員繞不開的話題就是:事務,作為一個簡化訪問數據庫的應用程序的編程模型。通過使用事務,應用程序可以忽略某些潛在的錯誤場景和並發問題,由數據庫負責處理它們。而並非每個應用程序

mysql 開發進階篇系列 12 問題(隔離級別的差異)

padding 排它 改變 level order 並發 aci delete 恢復 1. innodb在不同隔離級別下的一致性讀及鎖的差異   不同的隔離級別下,innodb處理sql 時采用的一致性讀策略和需要的鎖是不同的,同時,數據恢復和復制機制的特點,也對一些sql

Mysql ACID隔離級別

detail https itl lan http -i log blank cnblogs 參考: https://blog.csdn.net/csdnxingyuntian/article/details/57081233 https://www.cnblogs.com

淺析事務的傳播行為隔離級別

七個傳播行為,四個隔離級別。 Spring中事務的定義:Propagation(key屬性確定代理應該給哪個方法增加事務行為。這樣的屬性最重要的部份是傳播行為。)有以下選項可供使用: PROPAGATION_REQUIRED–支援當前事務,如果當前沒有事務,就

撩課-Mysql第16部分-事務併發/髒讀/幻讀/隔離級別

學習地址: 撩課-JavaWeb系列1之基礎語法-前端基礎 撩課-JavaWeb系列2之XML 撩課-JavaWeb系列3之MySQL 撩課-JavaWeb系列4之JDBC 撩課-JavaWeb系列5之web伺服器-idea 事務的併發問題 1.髒讀 老闆要給程式設

Spring的傳播行為隔離級別,你必須懂的

Spring事務中的傳播行為如下: Require:支援當前事務,如果沒有事務,就建一個新的,這是最常見的; Supports:支援當前事務,如果當前沒有事務,就以非事務方式執行; Mandatory:支援當前事務,如果當前沒有事務,就丟擲異常; Requires

Spring的傳播行為隔離級別

spring事務中的傳播行為如下: Require:支援當前事務,如果沒有事務,就建一個新的,這是最常見的; Supports:支援當前事務,如果當前沒有事務,就以非事務方式執行; Mandatory:支援當前事務,如果當前沒有事務,就丟擲異常; RequiresNew:新建事務,如果當前存在事務

事物的四大特性隔離級別

本篇講訴資料庫中事務的四大特性(ACID),並且將會詳細地說明事務的隔離級別。   如果一個數據庫聲稱支援事務的操作,那麼該資料庫必須要具備以下四個特性: ⑴ 原子性(Atomicity)  

關於MySQL隔離級別比較好的文章。

https://segmentfault.com/p/1210000010536201/read我所理解的髒讀,不可重複讀和幻讀。髒讀:某個事務已更新一份資料,另一個事務在此時讀取了同一份資料,由於某些原因,前一個事務會滾了操作,導致髒讀產生。不可重複讀:在一個事務的兩次查詢

資料庫事務隔離級別,事物邊界

1.資料庫事務的概念: •事務是指一組相互依賴的操作行為,如銀行交易、股票交易或網上購物。事務的成功取決於這些相互依賴的操作行為是否都能執行成功,只要有一個操作行為失敗,就意味著整個事務失敗。例如,Tom到銀行辦理轉賬事務,把100元錢轉到Jack的賬號上,這個事務包含以

資料庫隔離級別

併發控制主要是為了多執行緒操作時帶來的資源讀寫問題。如果不加以空間可能會出現死鎖,讀髒資料、不可重複讀、丟失更新等異常。 併發操作可以通過加鎖的方式進行控制,鎖又可分為樂觀鎖和悲觀鎖。     悲觀鎖(Pessimistic Locking)併發模式假定系統中存在足夠多的

innodb機制,七種型別的,事務隔離級別

1 共享/排他鎖(shared and exclusive Locks) 共享鎖(Share Locks,記為S鎖),讀取資料時加S鎖 排他鎖(eXclusive Locks,記為X鎖) 修改資料時加X鎖 共享鎖之間 不互斥,簡單記為: 讀讀可以並行 排他鎖與任何鎖互

資料庫事務的特點隔離級別

事務的四個特點 百度百科:資料庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。 事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向資料的資源。通過將一組相

隔離級別--mysql sql 20170526更新

刪掉了之前的部落格(摘抄,不精準,理解欠佳) 資料庫隔離級別: 資料庫事務的隔離級別有4個,由低到高依次為Read uncommitted、Read committed、Repeatable read、Serializable,這四個級別可以逐個解決髒讀、不可重複讀、幻

資料庫事務的四大特性隔離級別及測試

四大特性 ⑴ 原子性(Atomicity)   原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,這和前面兩篇部落格介紹事務的功能是一樣的概念,因此事務的操作如果成功就必須要完全應用到資料庫,如果操作失敗則不能對資料庫有任何影響。 ⑵ 一

SQL Server 事務隔離級別

上班途中,你在一處ATM機前停了下來。正當你在敲入密碼的時候,你的一位家人也正在鎮上的另一處TAM機上輸入密碼。你打算從某個還有500元餘額的賬戶上轉出400元,而你的家人想從同一賬戶取走300元。倘若沒有隔離級別的存在,麻煩就要來了......SQL Server 實現了

SQL Server 之 事務隔離級別實例講解

數據 potential ola sed http 高可用 獲取 簡介 set 原文:SQL Server 之 事務與隔離級別實例講解   SQL Server 實現了6個隔離級別來防止並發情況下,類似企圖並發的訪問或修改同一數據時問題的發生。本文將帶你體驗全部6個隔

Spring 事務傳播隔離級別描述

一. 傳播 : 描述在當前情況條件下,後續的事或物是以何種狀態或行為去呈現。       思考情