2009-10-26 9 views
0

Je reçois parfois des blocages dans le serveur sql. J'ai créé une fonction pour verrouiller les opérations hors base de données (traitement de carte de crédit) afin que les doublons ne puissent pas se produire. Mes fonctions sont les suivantes (désolé pour le tcl, mais le sql est assez clair). Quelqu'un peut-il voir pourquoi une impasse arrive de temps en temps ?????Obtenir deadlocks dans sqlserver

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]" 

} 

Répondre

1
  1. Essayez d'ajouter UPDLOCK au 1er sélection pour forcer un verrou exclusif trop

  2. Essayez sp_getapplock qui est prévu pour ce genre d'opération.

Je préfère le numéro 2, personnellement ...

+0

Je jure que je l'ai lu que holdlock comme UPDLOCK lol. Je suis sûr que tu l'as cloué. –

0

Il serait utile d'avoir le graphe de blocage.

Les interblocages SQL ne se produisent pas uniquement à cause des requêtes, mais tout aussi important est le schéma impliqué. Par exemple, vous pouvez obtenir un Reader-Writer deadlocks avec des requêtes parfaitement correctes et 'correctes' simplement parce que la lecture et l'écriture choisissent différents chemins d'accès aux données. Je pourrais voir cela se produire dans votre cas si un index sur timeActionMade existe sur GranularLocks qui ne couvre pas la colonne 'objet'. Mais encore une fois, la solution dépendra de ce que l'impasse est en cours.