2009-10-26 16 views
4

J'ai la routine suivante:TransactionScope et erreur: ORA-02049

For j = 1 To NumItems 
    dbValueLookup.Load(j) 
    Using scope As New TransactionScope() 
     For i = firstIndex To lastIndex 

      'dbValueLookup is basically just a Dictionary of items already in the DB 
      If dbValueLookup.ContainsKey(i) Then 
       'updateData is a subroutine that updates this row with new data 
       updateData(j,i) 
       rowsUpdated = rowsUpdated + 1 
       dbValueLookup.Remove(i) 
      Else 
       'updateData is a subroutine that adds a new row to DB 
       addData(j,i) 
       rowsAdded = rowsAdded + 1 
      End If 
     Next 

     If dbValueLookup.Count = 0 Then 
      'This commits the transaction - records will be updated when End Using is reached 
      scope.Complete() 
      If rowsAdded + rowsUpdated > 0 Then 
       ShowMessage("Records Updated: " + rowsUpdated.ToString() + " Records Added: " + rowsAdded.ToString()) 
      End If 

     Else 
      'We are left with data from the database that was not updated. This is a problem, so we don't "Complete" the scope. 
      'This will result in a rollback. 
      ShowWarningMessage("Incomplete Data for " + i.ToString()) 
     End If 
    End Using 
Next 

L'exécution de ce contre à la fois notre production et tester la base de données Oracle 11g de façon sporadique (ou s'il y a un modèle, je n'ai pas encore trouvé) génère l'erreur Oracle: ORA-02049: timeout: transaction distribuée en attente de verrouillage

Étant donné qu'il s'agit du seul processus exécuté sur la base de données de test, il ne devrait pas y avoir de problème avec les différents utilisateurs en compétition pour un verrou.

Des idées sur ce qui pourrait être à l'origine de cette erreur?

Merci d'avance.

Répondre

0

Il semble donc que vous devez avoir deux transactions en concurrence pour un verrouillage de ligne.

brainstorming Juste ici, mais si dbValueLookup.Count = 0, vous appellera addData (qui sonne comme il le fait un INSERT?), Mais vous ne serez pas appeler scope.Complete() de commettre votre transaction.

Je ne suis pas sûr si le End Using commettra toujours la transaction ou non.

Avez-vous vraiment besoin de créer le TransactionScope à chaque itération de la boucle? Pourquoi ne pas créer une transaction, faire toutes vos mises à jour/insertions, puis valider une fois?

Questions connexes