2008-11-20 4 views
4

Environnement

Je travaille sur une application C++ qui utilise SQL Native Client 9.0 pour communiquer avec un SQL Base de données Server 2000Dead-blocage créé par 2 connexions SQL, chaque transaction à l'aide, des tables différentes, contrainte de clé étrangère entre les deux tables

Scénario

  • 2 connexions sont ouvertes au SGBD
  • Chaque connexion est configuré pour utiliser les transactions
  • Une requête sur Connection1 travaux avec TableA
  • Une requête sur Connection2 travaux avec TableB
  • TableB a une contrainte de clé étrangère sur le champ key_id dans TableA

I construit la fonction qui effectue les opérations suivantes:

begin a transaction on Connection1 & Connection2 
prepare a query in TableA on Connection1 
prepare a query on TableB on Connection2 

begin loop over some_data 
    (1) insert into key_id on TableA 

    begin loop over some_other_data 
     (2) insert into TableB using same key_id as in Table A 
    end loop 
end loop 

commit on Connection1 
commit on Connection2 

Ce que je rencontrais cette requête était (1) exécute avec succès, mais dès que SQLExecute est appelé pour la requête (2), le débogueur se déclenche dans ne ayant jamais fumé Pays imaginaire.

La question

Suis-je diagnostiquer correctement ce qui se passe comme une question morte-lock?

Je réunis parce que Connection 1 crée une clé TableA mais pas commettre, alors Connection2 tente d'ajouter des informations à TableB que, en raison de la contrainte de clé étrangère, doit avoir la clé présente dans TableA. Pour cette raison, les blocs de requête SQLExecute, en attente de la transaction sur TableA pour terminer, ce qu'il ne peut pas faire jusqu'à ce que TableB termine son écriture, grâce à la façon dont le code a été écrit.

Notes additionnelles

je peux, et ont, codées autour de cette question, mais je veux assurer que ma compréhension du problème est correct.

Répondre

7

La contrainte de clé étrangère sur TableB par rapport à TableA doit vérifier pour confirmer l'existence de la clé. Il acceptera ou rejettera l'enregistrement TableB. Étant donné que l'enregistrement TableA contenant la clé est (sur une connexion différente) pas encore validée, la contrainte de clé étrangère doit attendre - l'insertion ne retournera pas jusqu'à ce que l'enregistrement TableA soit validée ou rolledback. Parce que le commit sur la première connexion attend l'insertion TableB pour retourner ... vous avez un interblocage.

En d'autres termes, vous avez raison.

Questions connexes