2009-11-09 3 views
2

J'ai quelques services de windwos. Ils obtiennent la colonne xml du serveur Sql manipuler et mettre à jour.xml Mise à jour de colonne et verrouillage dans SQL Server

service A- Obtient XML
service B- Obtient XML
service A- Mises à jour XML (il sera perdu)
service B- Mises à jour XML

je fermerai la ligne et j'utiliser le code suivant :

SqlCommand cmdUpdate = new SqlCommand(); 
      cmdUpdate.CommandText = "select MyXML from MyTable with(holdlock,rowlock) where [email protected]"; 
      cmdUpdate.Parameters.AddWithValue("@id", id); 

     using (SqlConnection conn = Helper.GetConnection()) 
     { 
      cmdUpdate.Connection = conn; 
      SqlTransaction ts = conn.BeginTransaction(); 
      cmdUpdate.Transaction = ts; 
      XElement elem = XElement.Parse(cmdUpdate.ExecuteScalar().ToString()); 
      UpdateXElement(elem); 
      cmdUpdate.Parameters.Clear(); 
      cmdUpdate.CommandText = "update MyTable set [email protected] where [email protected]"; 
      cmdUpdate.Parameters.AddWithValue("@id", id); 
      cmdUpdate.Parameters.AddWithValue("@xml", elem.ToString()); 

      cmdUpdate.ExecuteNonQuery(); 
      ts.Commit(); 
     } 
    }` 

se produit alors Deadlocks.

Avez-vous une meilleure idée, pour résoudre ce problème?

Merci

Répondre

0

Le scénario que vous décrivez n'est pas une impasse. Il est un argument de verrouillage, autrement dit, exactement ce que les serrures sont pour:

  1. service A- Obtient XML - Service A locks XML
  2. service B- Obtient XML - Services B places lock request which waits for service A to release the lock
  3. service A- XML ​​mises à jour (il sera perdu) - Service A should commit or rollback the transaction to release the lock.
  4. service B- Mises à jour XML - Service B acquires the lock on the XML and updates it

Service B seront congelés entre les étapes 2 et 3. Cela signifie que vous devez effectuer ces étapes le plus rapidement possible.

Mise à jour:

Vous utilisez un HOLDLOCK pour verrouiller la ligne dans une transaction.

HOLDLOCK place un verrou partagé qui est compatible avec un autre verrou partagé mais pas avec le verrou de mise à jour placé par .

Voici ce qui se passe:

  1. Service A place un verrou partagé sur row 1
    • Service B place un verrou partagé sur row 1
    • Service A tente de placer un verrou de mise à jour sur row 1 qui n'est pas compatible avec le verrou partagé placé par Service B à l'étape 2. Service A entre l'état d'attente (tout en maintenant un verrou partagé placé à l'étape 1).
    • Service B essaie de placer un verrou de mise à jour sur row 1 qui n'est pas compatible avec le verrou partagé placé par Service A à l'étape 1. Service B entre l'état d'attente. DEADLOCK.

Il n'y a pas de point à placer un verrou partagé dans une clause SELECT ici. Vous devez placer un UPDLOCK dans une clause SELECT à la place. Cela rendra les verrous de transaction complètement incompatibles et l'une ou l'autre transaction devra attendre l'achèvement d'autres transactions avant d'acquérir des verrous.

Dans ce scénario, les blocages sont impossibles.

+0

Oui, mais parfois "La transaction (ID de processus 108) a été bloquée sur les ressources de verrouillage avec un autre processus et a été choisie comme victime de l'interblocage. Exception. Mon code est-il responsable (à cause des verrous)? Comment éviter les blocages dans ce scénario? Merci –

+0

Merci beaucoup. Updlock a résolu le problème! merci –

Questions connexes