❶ sql server 怎麼保證查詢出的結果不能被其他電腦訪問,具體如下
這涉及到資料庫中,鎖的概念
首先,SQL Server更強調由系統來管理鎖。在用戶有SQL請求時,系統分析請求,自動在滿足鎖定條件和系統性能之間為資料庫加上適當的鎖,同時系統在運行期間常常自動進行優化處理,實行動態加鎖。也就是說,你的擔心是不必要的,SQLServer可以保證這種情況基本不會出現.如果特殊情況下,需要你手動出來,請參考下面文檔。
一. 為什麼要引入鎖
多個用戶同時對資料庫的並發操作時會帶來以下數據不一致的問題:
丟失更新
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 資料庫。
四 鎖定時間的長短
鎖保持的時間長度為保護所請求級別上的資源所需的時間長度。
用於保護讀取操作的共享鎖的保持時間取決於事務隔離級別。採用 READ COMMITTED 的默認事務隔離級別時,只在讀取頁的期間內控制共享鎖。在掃描中,直到在掃描內的下一頁上獲取鎖時才釋放鎖。如果指定 HOLDLOCK 提示或者將事務隔離級別設置為 REPEATABLE READ 或 SERIALIZABLE,則直到事務結束才釋放鎖。
根據為游標設置的並發選項,游標可以獲取共享模式的滾動鎖以保護提取。當需要滾動鎖時,直到下一次提取或關閉游標(以先發生者為准)時才釋放滾動鎖。但是,如果指定 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解鎖
幾個例子幫助大家加深印象
設table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
1)排它鎖
新建兩個連接
在第一個連接中執行以下語句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二個連接中執行以下語句
begin tran
select * from table1
where B='b2'
commit tran
若同時執行上述兩個語句,則select查詢必須等待update執行完畢才能執行即要等待30秒
2)共享鎖
在第一個連接中執行以下語句
begin tran
select * from table1 holdlock -holdlock人為加鎖
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二個連接中執行以下語句
begin tran
select A,C from table1
where B='b2'
update table1
set A='aa'
where B='b2'
commit tran
若同時執行上述兩個語句,則第二個連接中的select查詢可以執行
而update必須等待第一個事務釋放共享鎖轉為排它鎖後才能執行 即要等待30秒
3)死鎖
增設table2(D,E)
D E
d1 e1
d2 e2
在第一個連接中執行以下語句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30'
update table2
set D='d5'
where E='e1'
commit tran
在第二個連接中執行以下語句
begin tran
update table2
set D='d5'
where E='e1'
waitfor delay '00:00:10'
update table1
set A='aa'
where B='b2'
commit tran
同時執行,系統會檢測出死鎖,並中止進程
補充一點:
Sql Server2000支持的表級鎖定提示
HOLDLOCK 持有共享鎖,直到整個事務完成,應該在被鎖對象不需要時立即釋放,等於SERIALIZABLE事務隔離級別
NOLOCK 語句執行時不發出共享鎖,允許臟讀 ,等於 READ UNCOMMITTED事務隔離級別
PAGLOCK 在使用一個表鎖的地方用多個頁鎖
READPAST 讓sql server跳過任何鎖定行,執行事務,適用於READ UNCOMMITTED事務隔離級別只跳過RID鎖,不跳過頁,區域和表鎖
ROWLOCK 強制使用行鎖
TABLOCKX 強制使用獨占表級鎖,這個鎖在事務期間阻止任何其他事務使用這個表
UPLOCK 強制在讀表時使用更新而不用共享鎖
應用程序鎖:
應用程序鎖就是客戶端代碼生成的鎖,而不是sql server本身生成的鎖
處理應用程序鎖的兩個過程
sp_getapplock 鎖定應用程序資源
sp_releaseapplock 為應用程序資源解鎖
注意: 鎖定資料庫的一個表的區別
SELECT * FROM table WITH (HOLDLOCK) 其他事務可以讀取表,但不能更新刪除
SELECT * FROM table WITH (TABLOCKX) 其他事務不能讀取表,更新和刪除
❷ 為什麼在插入和刪除的時候用到ROWLOCK
確保數據的完成性.
有關鎖的概念和介紹如下:
SQL code
鎖的概述
一. 為什麼要引入鎖
多個用戶同時對資料庫的並發操作時會帶來以下數據不一致的問題:
丟失更新
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 資料庫。
四 鎖定時間的長短
鎖保持的時間長度為保護所請求級別上的資源所需的時間長度。
用於保護讀取操作的共享鎖的保持時間取決於事務隔離級別。採用 READ COMMITTED 的默認事務隔離級別時,只在讀取頁的期間內控制共享鎖。在掃描中,直到在掃描內的下一頁上獲取鎖時才釋放鎖。如果指定 HOLDLOCK 提示或者將事務隔離級別設置為 REPEATABLE READ 或 SERIALIZABLE,則直到事務結束才釋放鎖。
根據為游標設置的並發選項,游標可以獲取共享模式的滾動鎖以保護提取。當需要滾動鎖時,直到下一次提取或關閉游標(以先發生者為准)時才釋放滾動鎖。但是,如果指定 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解鎖
幾個例子幫助大家加深印象
設table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
1)排它鎖
新建兩個連接
在第一個連接中執行以下語句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二個連接中執行以下語句
begin tran
select * from table1
where B='b2'
commit tran
若同時執行上述兩個語句,則select查詢必須等待update執行完畢才能執行即要等待30秒
2)共享鎖
在第一個連接中執行以下語句
begin tran
select * from table1 holdlock -holdlock人為加鎖
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二個連接中執行以下語句
begin tran
select A,C from table1
where B='b2'
update table1
set A='aa'
where B='b2'
commit tran
若同時執行上述兩個語句,則第二個連接中的select查詢可以執行
而update必須等待第一個事務釋放共享鎖轉為排它鎖後才能執行 即要等待30秒
3)死鎖
增設table2(D,E)
D E
d1 e1
d2 e2
在第一個連接中執行以下語句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30'
update table2
set D='d5'
where E='e1'
commit tran
在第二個連接中執行以下語句
begin tran
update table2
set D='d5'
where E='e1'
waitfor delay '00:00:10'
update table1
set A='aa'
where B='b2'
commit tran
同時執行,系統會檢測出死鎖,並中止進程
補充一點:
Sql Server2000支持的表級鎖定提示
HOLDLOCK 持有共享鎖,直到整個事務完成,應該在被鎖對象不需要時立即釋放,等於SERIALIZABLE事務隔離級別
NOLOCK 語句執行時不發出共享鎖,允許臟讀 ,等於 READ UNCOMMITTED事務隔離級別
PAGLOCK 在使用一個表鎖的地方用多個頁鎖
READPAST 讓sql server跳過任何鎖定行,執行事務,適用於READ UNCOMMITTED事務隔離級別只跳過RID鎖,不跳過頁,區域和表鎖
ROWLOCK 強制使用行鎖
TABLOCKX 強制使用獨占表級鎖,這個鎖在事務期間阻止任何其他事務使用這個表
UPLOCK 強制在讀表時使用更新而不用共享鎖
應用程序鎖:
應用程序鎖就是客戶端代碼生成的鎖,而不是sql server本身生成的鎖
處理應用程序鎖的兩個過程
sp_getapplock 鎖定應用程序資源
sp_releaseapplock 為應用程序資源解鎖
注意: 鎖定資料庫的一個表的區別
SELECT * FROM table WITH (HOLDLOCK) 其他事務可以讀取表,但不能更新刪除
SELECT * FROM table WITH (TABLOCKX) 其他事務不能讀取表,更新和刪除
❸ 如何在SQL Server中鎖定某行記錄
SELECT au_lname FROM authors WITH (ROWLOCK )
鎖定提示 描述
HOLDLOCK 將共享鎖保留到事務完成,而不是在相應的表、行或數據頁不再需要時就立即釋放鎖。HOLDLOCK等同於SERIALIZABLE。
NOLOCK 不要發出共享鎖,並且不要提供排它鎖。當此選項生效時,可能會讀取未提交的事務或一組在讀取中間回滾的頁面。有可能發生臟讀。僅應用於 SELECT語句。
PAGLOCK 在通常使用單個表鎖的地方採用頁鎖。
READCOMMITTED 用與運行在提交讀隔離級別的事務相同的鎖語義執行掃描。默認情況下,SQLServer 2000 在此隔離級別上操作。
READPAST 跳過鎖定行。此選項導致事務跳過由其它事務鎖定的行(這些行平常會顯示在結果集內),而不是阻塞該事務,使其等待其它事務釋放在這些行上的鎖。READPAST 鎖提示僅適用於運行在提交讀隔離級別的事務,並且只在行級鎖之後讀取。僅適用於SELECT 語句。
READUNCOMMITTED 等同於NOLOCK。
REPEATABLEREAD 用與運行在可重復讀隔離級別的事務相同的鎖語義執行掃描。
ROWLOCK 使用行級鎖,而不使用粒度更粗的頁級鎖和表級鎖。
SERIALIZABLE 用與運行在可串列讀隔離級別的事務相同的鎖語義執行掃描。等同於HOLDLOCK。
TABLOCK 使用表鎖代替粒度更細的行級鎖或頁級鎖。在語句結束前,SQLServer 一直持有該鎖。但是,如果同時指定 HOLDLOCK,那麼在事務結束之前,鎖將被一直持有。
TABLOCKX 使用表的排它鎖。該鎖可以防止其它事務讀取或更新表,並在語句或事務結束前一直持有。
UPDLOCK 讀取表時使用更新鎖,而不使用共享鎖,並將鎖一直保留到語句或事務的結束。UPDLOCK 的優點是允許您讀取數據(不阻塞其它事務)並在以後更新數據,同時確保自從上次讀取數據後數據沒有被更改。
XLOCK 使用排它鎖並一直保持到由語句處理的所有數據上的事務結束時。可以使用 PAGLOCK或 TABLOCK 指定該鎖,這種情況下排它鎖適用於適當級別的粒度
❹ sql 的優化隱藏器是什麼
優化隱藏
概述
一般地,對查詢語句,查詢處理器創建了可以提高性能的執行規劃。然而,如果對某一個特定的查詢語句例如檢索、插入、刪除、修改,查詢處理器沒有創建最好的執行規劃,那麼用戶可以在查詢語句中增加優化隱藏來影響查詢處理器創建出最優的執行規劃。優化隱藏就是指在執行查詢語句、使用多表連接檢索或者指定查詢語句操作的對象表時,明確地指出應該使用的查詢方法、連接演算法或者對表的操作方式。當使用優化隱藏時,一定要認真考慮優化隱藏對性能的影響。在SQL Server 7.0中,提供了三種類型的優化隱藏,即查詢優化隱藏、連接優化隱藏和表優化隱藏。
查詢優化隱藏
查詢優化隱藏控制整個語句的執行規劃。可以通過在SQL語句的最後增加一個OPTION子句,來實現查詢優化隱藏。另外,還可以同時指定多個查詢優化隱藏,這些選項之間由逗號分割開來。使用Hash Group或者Order Group選項,可以為分組子句或者分組計運算元句產生合計數值,但是這兩個選項不能同時使用。在聯合Union運算符中,可以使用合並、散列和連接選項,這時既可以使用一個選項,也可以同時使用多個選項。當同時使用多個選項時,系統將在這幾個選項中選用成本最低的方法進行操作。當把返回查詢結果的時間作為關鍵因素時,應當使用選項Fast n,這樣可以最小化返回查詢語句所得到的前n條記錄的時間。如果需要固定在連接運算符中表的先後順序,那麼可以使用選項Force Order,該選項可以確保在連接運算符中指定的准確的表的順序。單個查詢語句可以使用多個處理器並行執行,選項MaxDop n就是為並行執行查詢語句,明確指定可以使用處理器的最大值。
連接優化隱藏
連接優化隱藏指定某一個連接運算應該如何最優地實現。連接就是把兩個或者多個表中的記錄連接起來,通常是連接兩個表中的記錄。在連接中,使用兩個表中的某些列組成連接的條件表達式。為了使用連接優化隱藏,可以在連接運算符之前使用四個關鍵字中的其中一個關鍵字,這四個關鍵字分別是Loop、Hash、Merge和Remote。使用不同的關鍵字,就是使用不同的連接演算法。當使用關鍵字Loop時,連接演算法就是在第一個表中,順序地閱讀表中的每一行。對於第一個表中的一行,順序地與第二個表中的每一行進行比較,如果滿足連接條件,那麼就得到在匹配的行。就這樣進行下去,直至得到滿足條件的全部匹配的行。當使用關鍵字Hash時,使用的連接演算法是這樣的,對於第一個表中的每一行,計算在連接中使用的該列的散列值,然後把該散列值存儲在散列表中,對於第二個表中的每一行,計算一個在連接中使用的該列的散列值,然後在散列表中尋找匹配的行。通過在散列表中尋找匹配的記錄,就可以得到滿足連接條件的記錄。如果使用關鍵字Merge,那麼可以根據連接列的順序,使用匹配和合並演算法,處理兩個表中的每一行,得到滿足連接條件的全部記錄。關鍵字Remote很少使用,只有當連接中的兩個表存儲在不同的系統中時,才可以使用。該關鍵字指定在連接運算符右端的表所在的系統,開始連接進程。
當指定連接優化隱藏時,查詢處理器強制多個連接運算符的順序和在每個連接中指定的表的順序。當沒有指定連接優化隱藏時,查詢處理器根據連接的表結構和連接條件選擇最有效的方法。另外,如果沒有指定連接優化隱藏,那麼查詢處理器可以重新安排表的順序,如果有多個連接運算符,那麼查詢處理器也可以重新安排連接運算的順序,這樣可以保證系統使用最有效的連接方法。
表優化隱藏
表優化隱藏指定在查詢語句中使用的單個基表的訪問特徵。通過在表名後面增加一個With子句,可以指定表的優化隱藏。在檢索、插入、修改和刪除等查詢語句中都可以使用表優化隱藏。對於多個優化隱藏,可以使用逗號或者空格分割開。
優化隱藏FastFirstRow最小化該查詢語句返回表中第一條記錄的時間。該選項與查優化隱藏的Fast 1完全等價。索引優化隱藏Index(IndexName)和Index(IndexID)指定在訪問該表時應該使用的索引名稱或者索引代號。0表示使用表掃描,1表示使用聚簇索引(如果有聚簇索引)。對於那些非聚簇索引,可以通過使用該索引的名稱,強制在查詢語句中使用。
行級鎖類型優化隱藏UpdLock使用修改行級鎖取代共享行級鎖。鎖度優化隱藏。這些鎖類型只能一次使用一個。選項NoLock和ReadUncommitted,表示查詢語句不能獲得共享鎖,忽略排它鎖,也就是說,即使在操作對象上有排它鎖,也可以繼續訪問該對象。這兩個關鍵字是等價的,並且只能用在SELECT語句中。選項PagLock使用共享數據頁鎖代替共享表鎖。RowLock使用共享行鎖代替共享頁鎖或者共享表鎖。TabLock獲取共享表鎖,該鎖一直保存到該語句的結束。如果指定了Holdlock或者Serializable選項,那麼鎖一直保存到該事務的結束。TabLockX獲取排它表鎖。
事務獨立等級優化隱藏。這些鎖類型只能一次使用一個。Holdlock或者Serializable佔有共享鎖,直到事務的結束,而不是在查詢語句不需要這些頁鎖或者表鎖時,就釋放它們。這兩個關鍵字等價。ReadCommitted佔有共享鎖,直到該語句的結束,但是允許其他進程修改讀過的數據,因此這種讀是不可重復的。RepeatableRead佔有鎖,防止其他進程修改在查詢語句中使用的數據。
鎖級表優化隱藏有兩種作用:提高並發性和提高在並行訪問同一個表的沖突保護。NoLock、RowLock和PagLock優化隱藏允許多個並發進程。注意,當使用NoLock時,因為它允許閱讀那些已經修改但是還沒有提交的數據,如果改變這些數據的事務被取消了,那麼該查詢語句得到的數據與資料庫中的內容是不一樣的。RowLock和PagLock可以提高系統級的性能,當並行查詢訪問同一個表中的不同數據時,他們不會放置大量的鎖。然而,在另外一些情況下,使用這些選項,由於附加的鎖開銷,會降低系統的性能。
選項TabLock和 TabLockX明確指定使用表鎖,防止並發訪問的沖突。事務獨立等級允許在單個語句中使用的鎖協議,而不管當前的事務獨立等級是什麼。ReadUncommitted、ReadCommitted、RepeatableRead和Serializable從最低的保護性和最高的並發性到最高的保護性和最低的並發性。
❺ sql進程鎖定如何處理
--1. 輸入 SP_lock
--SP_lock
--2. 查看 spid 數量較多,objld<>0的項目的SPID,如 61
--3. 查看該項目的進程
--dbcc inputbuffer (61)
--查到 Language Event 0 select * from tb_MQualityInfo with (holdlock updlock rowlock) where uid=159 類似信息
--若有 holdlock uplock rowlock 字樣的,則進程被鎖死,只有發生這種情況再做
--4.殺死該進程
--5.kill 61
--6.重新查看SP_lock
❻ SQL如何鎖定某行~用觸發器怎麼寫
create trigger tr_aa_up on 表名
for update
as
if exists (select 1 from inserted where ID=2 ) rollback
go
create trigger tr_aa_del on aa
for delete
as
if exists (select 1 from deleted where ID=2 ) rollback
go
如果有多個行,可以修改 select 1 from deleted where ID=2 這個語句
如 select 1 from deleted where ID in (2 ,3,4,5)
❼ sqlserver怎麼實現一個行鎖
1如何鎖一個表的某一行
SELECT*FROMtableROWLOCKWHEREid=1
2鎖定資料庫的一個表
SELECT*FROMtableWITH(HOLDLOCK)
加鎖語句:
sybase:
update表setcol1=col1where1=0;
MSSQL:
selectcol1from表(tablockx)where1=0;
oracle:
LOCKTABLE表INEXCLUSIVEMODE;
加鎖後其它人不可操作,直到加鎖用戶解鎖,用commit或rollback解鎖
❽ SQL 資料庫 鎖,有請高手給小弟分析
select查詢時是共享鎖,這時候還可以在其上疊加共享鎖,但不能加排他鎖。
DML操作時是排他鎖,這時候在其上不能再加任何類型的鎖。
因此同行數據有部分更新是不能讀該行沒正在更新的數據的。
實際上在實際數據應用中這種情況非常普遍,只要在寫SQL語句時注意利用好索引,加快語句的執行效率,另外一條需要記住的是在資料庫繁忙之時(如銀行上午9-11點和下午2-4點間櫃台業務繁忙,中心機房的資料庫很繁忙),不要執行大批量的數據查詢和更新操作。盡量將這些處理大量數據的操作放到資料庫空閑時間去做。
本人經常處理上千萬條記錄的表,只要掌握得當,這些問題應該不是個問題的。至於分兩張來做,還需要數據的同步,你還是解決了這個問題的。
使用高效的SQL語句,那些處理時間稍縱即逝,資料庫SQL操作也是有排隊機制的,如果因為SQL語句效率低下,造成後面的排隊時間等待過長,會time out 的。
因此只要使用高效的SQL語句,你說的這些問題是無需擔心的。
❾ sql 怎樣加行鎖
updatetable_namewith(rowlock)setcolumn_name=new_valuewhereyour_condition