数据库中死锁是什么产生的?

数据库中死锁是什么产生的?,第1张

数据库 *** 作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL

Server

2005,

现在似乎有了一种新的解决办法。

将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁。

use

Northwind

begin

tran

insert

into

Orders(CustomerId)

values(@#ALFKI@#)

waitfor

delay

@#00:00:05@#

select

*

from

Orders

where

CustomerId

=

@#ALFKI@#

commit

print

@#end

tran@#

SQL

Server对付死锁的办法是牺牲掉其中的一个,抛出异常,并且回滚事务。在SQL

Server

2000,语句一旦发生异常,T-SQL将不会继续运行,上面被牺牲的连接中,

print

@#end

tran@#语句将不会被运行,所以我们很难在SQL

Server

2000的T-SQL中对死锁进行进一步的处理。

现在不同了,SQL

Server

2005可以在T-SQL中对异常进行捕获,这样就给我们提供了一条处理死锁的途径:

下面利用的try

...

catch来解决死锁。

SET

XACT_ABORT

ON

declare

@r

int

set

@r

=

1

while

@r

<=

3

begin

begin

tran

begin

try 

insert

into

Orders(CustomerId)

values(@#ALFKI@#)

waitfor

delay

@#00:00:05@#

select

*

from

Orders

where

CustomerId

=

@#ALFKI@#

commit

break

end

try

begin

catch

rollback

waitfor

delay

@#00:00:03@#

set

@r

=

@r

+

1

continue

end

catch

end

解决方法当然就是重试,但捕获错误是前提。rollback后面的waitfor不可少,发生冲突后需要等待一段时间,@retry数目可以调整以应付不同的要求。

但是现在又面临一个新的问题:

错误被掩盖了,一但问题发生并且超过3次,异常却不会被抛出。SQL

Server

2005

有一个RaiseError语句,可以抛出异常,但却不能直接抛出原来的异常,所以需要重新定义发生的错误,现在,解决方案变成了这样:

declare

@r

int

set

@r

=

1

while

@r

<=

3

begin

begin

tran

begin

try 

insert

into

Orders(CustomerId)

values(@#ALFKI@#)

waitfor

delay

@#00:00:05@#

select

*

from

Orders

where

CustomerId

=

@#ALFKI@#

commit

break

end

try

begin

catch

rollback

waitfor

delay

@#00:00:03@#

set

@r

=

@r

+

1

continue

end

catch

end

if

ERROR_NUMBER()

<>

0

begin

declare

@ErrorMessage

nvarchar(4000)

declare

@ErrorSeverity

int

declare

@ErrorState

int

select

@ErrorMessage

=

ERROR_MESSAGE(),

@ErrorSeverity

=

ERROR_SEVERITY(),

@ErrorState

=

ERROR_STATE()

raiserror

(@ErrorMessage,

 

@ErrorSeverity,

 

@ErrorState

 

)

end

多线程是很容易造成死锁,一般情况下死锁都是因为并发 *** 作引起的。我不懂JAVA,但死锁这个问题每种开发工具和数据库都会碰到.解决办法是:

1、程序方面优化算法(如有序资源分配法、银行算法等),在一个程序里,能不用多线程更新同一张数据库表 尽量不要用,如果要用,其避免死锁的算法就很复杂。

2、数据库方面设置等待超时时间

3、发生死锁后直接KILL掉数据库进程

建议:

1、使用事件探查器,跟踪一下SQL在死锁之前执行了哪些SQL语句

2、多数死锁是因为程序没有经过严格的测试造成的

3、少部分原因是因为触发器嵌套造成的,SQL有内部机制,当嵌套到一定的层级,就自动终止掉相关的进程

愿早日解决问题


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10872313.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-11
下一篇 2023-05-11

发表评论

登录后才能评论

评论列表(0条)

保存