数据库死锁处理方法

数据库死锁处理方法,第1张

mysql数据死锁解决方法如下:

1、对于按钮等控件,点击后使其立刻失效,不让用户重复点击,避免对同时对同一条记录 *** 作。

2、使用乐观锁进行控制。乐观锁大多是基于数据版本(Version)记录机制实现。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是 通过为数据库表增加一个“version”字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数 据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。乐观锁机制避免了长事务中的数据 库加锁开销(用户A和用户B *** 作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系统整体性能表现。Hibernate 在其数据访问引擎中内置了乐观锁实现。需要注意的是,由于乐观锁机制是在系统中实现,来自外部系统的用户更新 *** 作不受系统的控制,因此可能会造 成脏数据被更新到数据库中。

1、要求每个事务一次就将所有要使用的数据全部加锁,否则不能执行。

2、采用按序加锁法.预先规定一个封锁顺序,所有的事务都必须按这个顺序对数据执行封锁。

3、不采取任何措施来预防死锁的发生,而是周期性地检查系统中是否有死锁.如果发现死锁就设法解除。

数据库 *** 作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过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


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存