关于TABLE的死锁问题,你敢来看吗

chenjunsheep 2008-07-16 07:01:13
执行步骤是这样的:
 ①执行SQL语句让线程死锁(死锁表David01 David02,见附文)
 ②强制KILL掉该死锁线程
 ③再次访问表David01,David02(用SELECT语句访问表)
问题:执行到③的SELECT语句后,系统无法进行下去,用户一直处于等待状态...寒

附(让线程死锁的代码):
begin tran 

update David01

set A='aa'

where B='b2'

waitfor delay '00:00:5'

update David02

set D='d5'

where E='e1'



--In the second connection

begin tran

update David02

set D='d5'

where E='e1'

waitfor delay '00:00:3'

update David01

set A='aa'

where B='b2'


为什么强制终止线程后,该表不能再次被访问呢?
还是说虽然死锁线程被终止掉了,但表自身的锁还没被解掉呢?
大虾们...HELP!
第二次发帖,大家多照顾照顾へへ
...全文
138 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhiguo2008 2008-07-21
  • 打赏
  • 举报
回复
,,,,,
nzperfect 2008-07-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 chenjunsheep 的回复:]
引用 5 楼 zhuyx808 的回复:
你第2步怎么搞的?能不能看看你的代码啊

SQL codedeclare@spnvarchar(100),@sqlnvarchar(1000)set@sp=(Selectspidfrommaster..sysprocesseswhereblocked>0)set@sql='kill'+@spexec(@sql)
上面这段代码我是放到SQL服务的JOB里面定时执行的,也就是步骤2的执行代码,大家可以看看
[/Quote]

这个不管用,你那两个事务,是一种死锁,不是堵塞,所以你用
Select spid from master..sysprocesses where blocked > 0
无法查找那两个进程,所以kill不掉的。

你用sp_lock查看那两个进程,然后去kill掉,就可以查询这两个表了。
chenjunsheep 2008-07-17
  • 打赏
  • 举报
回复
我是想问,当执行到第③步的时候,为什么一个简单的SELECT查询都会让用户一直处于等待状态...
Garnett_KG 2008-07-17
  • 打赏
  • 举报
回复
据说站在火星上看地球,唯一能看得见的就是楼主的小JJ
nzperfect 2008-07-17
  • 打赏
  • 举报
回复
楼主想说什么还是想问什么?
chenjunsheep 2008-07-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zhuyx808 的回复:]
你第2步怎么搞的?能不能看看你的代码啊
[/Quote]
declare @sp nvarchar(100),@sql nvarchar(1000)
set @sp = (Select spid from master..sysprocesses where blocked > 0)
set @sql = 'kill '+@sp
exec(@sql)

上面这段代码我是放到SQL服务的JOB里面定时执行的,也就是步骤2的执行代码,大家可以看看
zhuyx808 2008-07-17
  • 打赏
  • 举报
回复
你第2步怎么搞的?能不能看看你的代码啊
chenjunsheep 2008-07-17
  • 打赏
  • 举报
回复
这贴快沉了,顶起来!
llj0209013 2008-07-17
  • 打赏
  • 举报
回复
我试了一下,第一次出现这个:

消息 233,级别 20,状态 0,第 0 行
在向服务器发送请求时发生传输级错误。 (provider: 共享内存提供程序, error: 0 - 管道的另一端上无任何进程。)

nzperfect 2008-07-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 chenjunsheep 的回复:]
引用 5 楼 zhuyx808 的回复:
你第2步怎么搞的?能不能看看你的代码啊

SQL codedeclare@spnvarchar(100),@sqlnvarchar(1000)set@sp=(Selectspidfrommaster..sysprocesseswhereblocked>0)set@sql='kill'+@spexec(@sql)
上面这段代码我是放到SQL服务的JOB里面定时执行的,也就是步骤2的执行代码,大家可以看看
[/Quote]

换成:
create table #(spid varchar(20),dbid varchar(10),objid varchar(20),indid varchar(10),type varchar(20),
resource varchar(20),mode varchar(10),status varchar(20))
insert into # exec sp_lock
select distinct identity(int,1,1) as id, spid into #2 from # where mode in ('ix','x') and spid<>@@spid
declare @i int set @i=1
declare @spid int
while @i<=(select max(id) from #2)
begin
select @spid=spid from #2 where id=@i
exec('kill ' + @spid)
set @i= @i+1
end
drop table #,#2
nzperfect 2008-07-17
  • 打赏
  • 举报
回复
进程如果kill掉,sql server 会自动rollback 的。就不会管你commit 和 rollback 了。
楼主的问题原因主要是它没有kill掉进程。
sdxiong 2008-07-17
  • 打赏
  • 举报
回复
因为你两段代码都只有begin tran而没有commit或rollback

所以被kill后再执行时,仍要等待另一事务的结束。
Garnett_KG 2008-07-17
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 chenjunsheep 的回复:]
我是想问,当执行到第③步的时候,为什么一个简单的SELECT查询都会让用户一直处于等待状态...
[/Quote]


很简单啊,你的第一个Transction 并没有提交.
没有被你KILL掉的那SPID还握有独占锁.



begin tran

update David01

set A='aa'

where B='b2'

waitfor delay '00:00:5'

update David02

set D='d5'

where E='e1'



--In the second connection

begin tran

update David02

set D='d5'

where E='e1'

waitfor delay '00:00:3'

update David01

set A='aa'

where B='b2'
胡矣 2008-07-16
  • 打赏
  • 举报
回复
新技术前沿
牛啊
chenjunsheep 2008-07-16
  • 打赏
  • 举报
回复
补充一下测试数据的SCRIPT
create table  David01( 

A varchar(2)

,B varchar(2)

,C varchar(2))



--insert data

insert into David01

select 'a1','b1','c1'

union all select 'a2','b2','c2'

union all select 'a3','b3','c3'



--create table David02

create table David02

(D varchar(2)

,E varchar(2))



----insert data

insert into David02

select 'd1','e1'

union all select 'd2','e2'

6,129

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 新技术前沿
社区管理员
  • 新技术前沿社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧