代码之家  ›  专栏  ›  技术社区  ›  Byron Whitlock

获取sqlserver中的死锁

  •  0
  • Byron Whitlock  · 技术社区  · 15 年前

    我偶尔会在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]"
    
    }
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   gbn    15 年前
    1. 尝试将updlock添加到第一个select以强制独占锁定

    2. 尝试 sp_getapplock 这是为这种操作提供的。

    我个人更喜欢2号…

        2
  •  0
  •   Remus Rusanu    15 年前

    使用死锁图是很有用的。

    SQL死锁的发生不仅是因为涉及到查询,而且涉及到的模式也同样重要。例如,您可以得到 Reader-Writer deadlocks 使用完全有效和“正确”的查询仅仅是因为读和写选择了不同的数据访问路径。如果在不包含“object”列的granularlocks上存在TimeActionMake索引,我可以在您的案例中看到这种情况。但同样,解决方案将取决于实际的死锁依赖于什么。

    推荐文章