我自己的資料庫表記錄死鎖後的 根據以下資料的 解決方案:
1. 先根據以下語句 查詢 哪些表被 死鎖,及 死鎖的 spid
SELECT request_session_id spid,OBJECT_NAME(resource_associated_entity_id)tableNameFROMsys.dm_tran_locksWHERE resource_type='OBJECT'
2. 再根據以上 語句查詢出來的 spid 通過以下存儲過程 查詢是哪台機客戶機 在操作,造成的死鎖
exec sp_who2 'xxx' --xxx 是 spid 替換進去就好,就可以看到是哪台機造成的死鎖.
3. 最後通過 以下語句來清退程序,(當然我這次是因為查到是哪機子在操作,是以讓那台機子的客戶機退出用戶端 就可以了.)
KILL xxx --xxx 是spid 執行就好
方法一:
前些天寫一個存儲過程,存儲過程中使用了事務,後來我把一些代碼注釋掉來進行調試找錯,突然發現一張表被鎖住了,原來是建立事務的代碼忘記注釋掉。本文表鎖住了的解決方法。
-
其實不光是上面描述的情況會鎖住表,還有很多種場景會使表放生死鎖,解鎖其實很簡單,下面用一個示例來講解:
1 首先建立一個測試用的表:
複制代碼 代碼如下:
CREATE TABLE Test
(
TID INT IDENTITY(1,1)
)
2 執行下面的SQL語句将此表鎖住:
複制代碼 代碼如下:
SELECT * FROM Test WITH (TABLOCKX)
3 通過下面的語句可以檢視目前庫中有哪些表是發生死鎖的:
複制代碼 代碼如下:
SELECT request_session_id spid,OBJECT_NAME(resource_associated_entity_id)tableName
FROM sys.dm_tran_locks
WHERE resource_type='OBJECT '
4 上面語句執行結果如下:
spid :被鎖程序ID。
tableName:發生死鎖的表名。
5 隻需要使用kill關鍵字來殺掉被鎖的程序ID就可以對表進行解鎖:
方法二:
SQL Server死鎖使我們經常遇到的問題,下面就為您介紹如何查詢SQL Server死鎖,希望對您學習SQL Server死鎖方面能有所幫助。
SQL Server死鎖的查詢方法:
exec master.dbo.p_lockinfo 0,0 ---顯示死鎖的程序,不顯示正常的程序
exec master.dbo.p_lockinfo 1,0 ---殺死死鎖的程序,不顯示正常的程序
SQL Server死鎖的解除方法:
Create [email protected]_lock_spid bit=1, --是否殺掉死鎖的程序,1 殺掉, 0 僅顯示
@show_spid_if_nolock bit=1 --如果沒有死鎖的程序,是否顯示正常程序資訊,1 顯示,0 不顯示
as
declare @count int,@s nvarchar(1000),@i int
select id=identity(int,1,1),标志,
程序ID=spid,線程ID=kpid,塊程序ID=blocked,資料庫ID=dbid,
資料庫名=db_name(dbid),使用者ID=uid,使用者名=loginame,累計CPU時間=cpu,
登陸時間=login_time,打開事務數=open_tran, 程序狀态=status,
工作站名=hostname,應用程式名=program_name,工作站程序ID=hostprocess,
域名=nt_domain,網卡位址=net_addressinto #t from(select 标志='死鎖的程序',
spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,
status,hostname,program_name,hostprocess,nt_domain,net_address,
s1=a.spid,s2=0
from master..sysprocesses a join(select blocked from master..sysprocesses group byblocked
)bon a.spid=b.blocked where a.blocked=0
union all
select '|_犧牲品_>',
spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,
status,hostname,program_name,hostprocess,nt_domain,net_address,
s1=blocked,s2=1
from master..sysprocesses a where blocked<>0)aorder bys1,s2select @count=@@rowcount,@i=1
if @count=0 and @show_spid_if_nolock=1
begin
insert#tselect 标志='正常的程序',
spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,
open_tran,status,hostname,program_name,hostprocess,nt_domain,net_addressfrommaster..sysprocessesset @count=@@rowcount
end
if @count>0
begin
create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))if @kill_lock_spid=1
begin
declare @spid varchar(10),@标志 varchar(10)while @i<[email protected]
begin
select @spid=程序ID,@标志=标志 from #t [email protected]
insert #t1 exec('dbcc inputbuffer('[email protected]+')')if @标志='死鎖的程序' exec('kill'[email protected])set @[email protected]+1
end
end
else
while @i<[email protected]
begin
select @s='dbcc inputbuffer('+cast(程序ID as varchar)+')' from #t [email protected]
insert #t1 exec(@s)set @[email protected]+1
end
select a.*,程序的SQL語句=b.EventInfofrom #t a join #t1 b on a.id=b.idend
方法三:
1、select * from sys.dm_tran_locks或sp_LOCK 檢視request_node 字段中為'X'(排他鎖)或'IX'(意向排他鎖)
2、用sp_who2 + pid(程序ID) 檢視程序的詳細資訊
3、用dbcc inputbuffer(pid) 檢視一起死鎖的語句内容
以上方法應該能解決你的問題。