SQL SERVER 中如何使用鎖

2021-09-08 14:26:52 字數 4701 閱讀 1949

多個使用者同時對資料庫的併發操作時會帶來以下資料不一致的問題: 併發控制的主要方法是封鎖,鎖就是在一段時間內禁止使用者做某些操作以避免產生資料不一致 sql server支援的鎖粒度可以分為為行、頁、鍵、鍵範圍、索引、表或資料庫獲取鎖

一. 為什麼要引入鎖

多個使用者同時對資料庫的併發操作時會帶來以下資料不一致的問題:

-丟失更新

a,b兩個使用者讀同一資料並進行修改,其中乙個使用者的修改結果破壞了另乙個修改的結果,比如訂票系統

-髒讀

a使用者修改了資料,隨後b使用者又讀出該資料,但a使用者因為某些原因取消了對資料的修改,資料恢復原值,此時b得到的資料就與資料庫內的資料產生了不一致

-不可重複讀

a使用者讀取資料,隨後b使用者讀出該資料並修改,此時a使用者再讀取資料時發現前後兩次的值不一致

併發控制的主要方法是封鎖,鎖就是在一段時間內禁止使用者做某些操作以避免產生資料不一致

二.鎖的分類

鎖的類別有兩種分法:

1. 從資料庫系統的角度來看:分為獨佔鎖(即排它鎖),共享鎖和更新鎖

ms-sql server 使用以下資源鎖模式。

鎖模式描述

共享 (s) 用於不更改或不更新資料的操作(唯讀操作),如 select 語句。

更新 (u) 用於可更新的資源中。防止當多個會話在讀取、鎖定以及隨後可能進行的資源更新時發生常見形式的死鎖。

排它 (x) 用於資料修改操作,例如 insert、update 或 delete。確保不會同時同一資源進行多重更新。

意向鎖 用於建立鎖的層次結構。意向鎖的型別為:意向共享 (is)、意向排它 (ix) 以及與意向排它共享 (six)。

架構鎖 在執行依賴於表架構的操作時使用。架構鎖的型別為:架構修改 (sch-m) 和架構穩定性 (sch-s)。

大容量更新 (bu) 向表中大容量複製資料並指定了 tablock 提示時使用。

-共享鎖

共享 (s) 鎖允許併發事務讀取 (select) 乙個資源。資源上存在共享 (s) 鎖時,任何其它事務都不能修改資料。一旦已經讀取資料,便立即釋放資源上的共享 (s) 鎖,除非將事務隔離級別設定為可重複讀或更高階別,或者在事務生存週期內用鎖定提示保留共享 (s) 鎖。

-更新鎖

更新 (u) 鎖可以防止通常形式的死鎖。一般更新模式由乙個事務組成,此事務讀取記錄,獲取資源(頁或行)的共享 (s) 鎖,然後修改行,此操作要求鎖轉換為排它 (x) 鎖。如果兩個事務獲得了資源上的共享模式鎖,然後試圖同時更新資料,則乙個事務嘗試將鎖轉換為排它 (x) 鎖。共享模式到排它鎖的轉換必須等待一段時間,因為乙個事務的排它鎖與其它事務的共享模式鎖不相容;發生鎖等待。第二個事務試圖獲取排它 (x) 鎖以進行更新。由於兩個事務都要轉換為排它 (x) 鎖,並且每個事務都等待另乙個事務釋放共享模式鎖,因此發生死鎖。

若要避免這種潛在的死鎖問題,請使用更新 (u) 鎖。一次只有乙個事務可以獲得資源的更新 (u) 鎖。如果事務修改資源,則更新 (u) 鎖轉換為排它 (x) 鎖。否則,鎖轉換為共享鎖。

-排它鎖

排它 (x) 鎖可以防止併發事務對資源進行訪問。其它事務不能讀取或修改排它 (x) 鎖鎖定的資料。

-意向鎖

意向鎖表示 sql server 需要在層次結構中的某些底層資源上獲取共享 (s) 鎖或排它 (x) 鎖。例如,放置在表級的共享意向鎖表示事務打算在表中的頁或行上放置共享 (s) 鎖。在表級設定意向鎖可防止另乙個事務隨後在包含那一頁的表上獲取排它 (x) 鎖。意向鎖可以提高效能,因為 sql server 僅在表級檢查意向鎖來確定事務是否可以安全地獲取該錶上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。

意向鎖包括意向共享 (is)、意向排它 (ix) 以及與意向排它共享 (six)。

鎖模式 描述

意向共享 (is) 通過在各資源上放置 s 鎖,表明事務的意向是讀取層次結構中的部分(而不是全部)底層資源。

意向排它 (ix) 通過在各資源上放置 x 鎖,表明事務的意向是修改層次結構中的部分(而不是全部)底層資源。ix 是 is 的超集。

與意向排它共享 (six) 通過在各資源上放置 ix 鎖,表明事務的意向是讀取層次結構中的全部底層資源並修改部分(而不是全部)底層資源。允許頂層資源上的併發 is 鎖。例如,表的 six 鎖在表上放置乙個 six 鎖(允許併發 is 鎖),在當前所修改頁上放置 ix 鎖(在已修改行上放置 x 鎖)。雖然每個資源在一段時間內只能有乙個 six 鎖,以防止其它事務對資源進行更新,但是其它事務可以通過獲取表級的 is 鎖來讀取層次結構中的底層資源。

-獨佔鎖:只允許進行鎖定操作的程式使用,其他任何對他的操作均不會被接受。執行資料更新命令時,sql server會自動使用獨佔鎖。當物件上有其他鎖存在時,無法對其加獨佔鎖。

共享鎖:共享鎖鎖定的資源可以被其他使用者讀取,但其他使用者無法修改它,在執行select時,sql server會對物件加共享鎖。

更新鎖:當sql server準備更新資料時,它首先對資料物件作更新鎖鎖定,這樣資料將不能被修改,但可以讀取。等到sql server確定要進行更新資料操作時,他會自動將更新鎖換為獨佔鎖,當物件上有其他鎖存在時,無法對其加更新鎖。

2. 從程式設計師的角度看:分為樂觀鎖和悲觀鎖。

樂觀鎖:完全依靠資料庫來管理鎖的工作。

悲觀鎖:程式設計師自己管理資料或物件上的鎖處理。

ms-sqlserver 使用鎖在多個同時在資料庫內執行修改的使用者間實現悲觀併發控制

三.鎖的粒度

鎖粒度是被封鎖目標的大小,封鎖粒度小則併發性高,但開銷大,封鎖粒度大則併發性低但開銷小

sql server支援的鎖粒度可以分為為行、頁、鍵、鍵範圍、索引、表或資料庫獲取鎖

資源 描述

rid 行識別符號。用於單獨鎖定表中的一行。

鍵 索引中的行鎖。用於保護可序列事務中的鍵範圍。

頁 8 千位元組 (kb) 的資料頁或索引頁。

擴充套件盤區 相鄰的八個資料頁或索引頁構成的一組。

表 包括所有資料和索引在內的整個表。

db 資料庫。

四.鎖定時間的長短

鎖保持的時間長度為保護所請求級別上的資源所需的時間長度。

根據為游標設定的併發選項,游標可以獲取共享模式的滾動鎖以保護提取。當需要滾動鎖時,直到下一次提取或關閉游標(以先發生者為準)時才釋放滾動鎖。但是,如果指定 holdlock,則直到事務結束才釋放滾動鎖。

用於保護更新的排它鎖將直到事務結束才釋放。

如果乙個連線試圖獲取乙個鎖,而該鎖與另乙個連線所控制的鎖衝突,則試圖獲取鎖的連線將一直阻塞到:

將衝突鎖釋放而且連線獲取了所請求的鎖。

連線的超時間隔已到期。預設情況下沒有超時間隔,但是一些應用程式設定超時間隔以防止無限期等待

五.sql server 中鎖的自定義

1 處理死鎖和設定死鎖優先順序

死鎖就是多個使用者申請不同封鎖,由於申請者均擁有一部分封鎖權而又等待其他使用者擁有的部分封鎖而引起的無休止的等待

可以使用set deadlock_priority控制在發生死鎖情況時會話的反應方式。如果兩個程序都鎖定資料,並且直到其它程序釋放自己的鎖時,每個程序才能釋放自己的鎖,即發生死鎖情況。

2 處理超時和設定鎖超時持續時間。

@@lock_timeout 返回當前會話的當前鎖超時設定,單位為毫秒

set lock_timeout 設定允許應用程式設定語句等待阻塞資源的最長時間。當語句等待的時間大於 lock_timeout 設定時,系統將自動取消阻塞的語句,並給應用程式返回"已超過了鎖請求超時時段"的 1222 號錯誤資訊

示例 下例將鎖超時期限設定為 1,800 毫秒。

set lock_timeout 1800

3) 設定事務隔離級別。

4 ) 對 select、insert、update 和 delete 語句使用表級鎖定提示。

5) 配置索引的鎖定粒度

可以使用 sp_indexoption 系統儲存過程來設定用於索引的鎖定粒度

六.檢視鎖的資訊

1 執行 exec sp_lock 報告有關鎖的資訊

2 查詢分析器中按ctrl+2可以看到鎖的資訊

七.使用注意事項

如何避免死鎖

1 使用事務時,盡量縮短事務的邏輯處理過程,及早提交或回滾事務;

2 設定死鎖超時引數為合理範圍,如:3分鐘-10分種;超過時間,自動放棄本次操作,避免程序懸掛;

3 優化程式,檢查並避免死鎖現象出現;

4 .對所有的指令碼和sp都要仔細測試,在正是版本之前。

5 所有的sp都要有錯誤處理(通過@error)

6 一般不要修改sql server事務的預設級別。不推薦強行加鎖。

八.幾個有關鎖的問題

1 如何鎖乙個表的某一行

set transaction isolation level read uncommitted

select * from table rowlock where id = 1

2 鎖定資料庫的乙個表

select * from table with (holdlock)

加鎖語句:

sybase:

update 表 set col1=col1 where 1=0 ;

mssql:

select col1 from 表 (tablockx) where 1=0 ;

oracle:

lock table 表 in exclusive mode ;

加鎖後其它人不可操作,直到加鎖使用者解鎖,用commit或rollback解鎖。

sqlserver中鎖表應用

鎖乙個sql表的語句是sql 資料庫使用者都需要知道的,下面就將為您介紹鎖sql表的語句,希望對您學習鎖sql表方面能有所幫助。鎖定資料庫的乙個表 select from table with holdlock 注意 鎖定資料庫的乙個表的區別 select from table with holdl...

SQL Server 中 ROWLOCK 行級鎖

一 rowlock的使用 1 rowlock行級鎖確保,在使用者取得被更新的行,到該行進行更新,這段時間內不被其它使用者所修改。因而行級鎖即可保證資料的一致性,又能提高資料操作的併發性。2 rowlock告訴sql server只使用行級鎖,rowlock語法可以使用在select,update和d...

SqlServer中的更新鎖 UPDLOCK

updlock.updlock 的優點是允許您讀取資料 不阻塞其它事務 並在以後更新資料,同時確保自從上次讀取資料後資料沒有被更改。當我們用updlock來讀取記錄時可以對取到的記錄加上更新鎖,從而加上鎖的記錄在其它的執行緒中是不能更改的只能等本執行緒的事務結束後才能更改.示例 測試 在另乙個查詢裡...