在sql server中获取死锁
Posted
技术标签:
【中文标题】在sql server中获取死锁【英文标题】:Getting deadlocks in sqlserver 【发布时间】:2009-10-26 20:59:25 【问题描述】:我偶尔会在 sql server 中遇到死锁。我创建了一个用于锁定非数据库操作(信用卡处理)的函数,因此不会发生重复。我的函数如下(对不起tcl,但是sql已经够清楚了)。谁能看到为什么偶尔会发生死锁????
proc ims_syn_lock_object db object timeout 30 wait 1
if [catch
while true
am_dbtransaction begin $db
# read the object locks that aren't timed out
set result [am_db1cell $db "SELECT object from GranularLocks WITH (ROWLOCK,HOLDLOCK) where object = [ns_dbquotevalue $object] AND timeActionMade > DATEADD(second,-timeout, GETDATE())"]
# check to see if this object is locked and not timed out
if [string equal "" $result]
break;
else
# another process has this object and it is not timed out.
# release the row lock
am_dbtransaction rollback $db
if $wait
# sleep for between 400 and 800 miliseconds
sleep [expr [ns_rand 400] + 400]
else
# we aren't waiting on locked resources.
return 0;
# either the object lock has timed out, or the object isn't locked
# create the object lock.
ns_db dml $db "DELETE FROM GranularLocks WHERE object = [ns_dbquotevalue $object]"
ns_db dml $db "INSERT INTO GranularLocks(object,timeout) VALUES ([ns_dbquotevalue $object],[ns_dbquotevalue $timeout int])"
# releases the row lock and commits the transaction
am_dbtransaction commit $db
errMsg]
ns_log Notice "Could not lock $object. $errMsg"
catch
am_dbtransaction rollback $db
errMsg
return 0
return 1
proc ims_syn_unlock_object db object
#simply remove the objects lock
ns_db dml $db "DELETE FROM GranularLocks WHERE object = [ns_dbquotevalue $object]"
【问题讨论】:
【参考方案1】:尝试将 UPDLOCK 添加到第一个选择以强制排他锁
试试为这种操作提供的sp_getapplock
。
我个人更喜欢 2 号...
【讨论】:
我发誓我已经把那个holdlock读成updlock了,哈哈。我很确定你成功了。【参考方案2】:有死锁图会很有用。
SQL 死锁的发生不仅是因为涉及的查询,而且同样重要的是涉及的架构。例如,您可以获得具有完全有效和“正确”查询的Reader-Writer deadlocks,这仅仅是因为读取和写入选择了不同的数据访问路径。如果在不覆盖“对象”列的 GranularLocks 上存在 timeActionMade 索引,我可以看到这种情况发生。但同样,解决方案将取决于实际的死锁是什么。
【讨论】:
以上是关于在sql server中获取死锁的主要内容,如果未能解决你的问题,请参考以下文章