Problèmes avec TransactionScope et Oracle

nous avons écrit en C# 3.5 client de parler à une base de données Oracle (11g) à l'aide de la ODP.NET.

Cette application dispose d'un processus de traitement par lots où une longue tâche en cours d'exécution est effectué divers appels à la base de données au sein d'une TransactionScope.

Sur notre environnement de développement tout va bien, mais à l'UAT de l'environnement de l'un de nos clients (qui a des charges de données), deux en alternance (parfois l'un, parfois l'autre...) des erreurs se produisent:

  1. Incapable de s'engager dans une transaction distribuée
  2. La transaction a été annulée. (exception interne: Délai d'expiration de Transaction)

Nous utilisons actuellement un délai de un jour pour l'opération (à des fins de test).

L'exécution dudit procédé sur l'UAT l'environnement est la cause d'arrêter après approx. 10 minutes avec l'une des exceptions ci-dessus, donc aucun moyen, près de la valeur de délai d'expiration.

Voici un extrait de la stacktrace pour la deuxième erreur:

at System.Transactions.TransactionStatePromotedAborted.CreateAbortingClone(InternalTransaction tx)
   at System.Transactions.DependentTransaction..ctor(IsolationLevel isoLevel, InternalTransaction internalTransaction, Boolean blocking)
   at System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption)
   at System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent)
   at System.Transactions.TransactionScope.PushScope()
   at System.Transactions.TransactionScope..ctor(TransactionScopeOption scopeOption)
   at System.Transactions.TransactionScope..ctor()
   at Application.Domain.DataAccess.Oracle.EntityDaoBase`2.SaveItem(TEntity item, EntityReference`1 user)

Le processus tente d'enregistrer un élément de la DB à l'intérieur de l'étendue de la transaction, mais la stacktrace montre que le constructeur est frappé pour la classe TransactionScope en ce sens qu'elle crée un nouveau TransactionScope.

Suis-je droit?

Parce que je ne connais pas trop les rouages de la TransactionScope, mais il semble que lorsque vous appelez une méthode dans le champ d'application, il va créer une nouvelle transaction (assumingly héritant de la température ambiante de la transaction).

Pourrait-il être que si je ne me trompe, que cette nouvelle transaction n'hérite pas de la corriger délai d'attente (mais celui par défaut), de sorte qu'une transaction imbriquée sera la cause de cette exception délai?

Si pas, des idées sur ce que ça peut être? Sur une note de côté, il n'y a pas de transactions imbriquées définis dans les méthodes appelé à partir de la température ambiante de la transaction.

Toute aide serait grandement appréciée!

Edit 1:

Simplifié extrait de code de la fonction:

public void SomeLengthyBatchProcess()
{
   using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0)))
   {
       foreach (var item in Items)
       {
          SaveItemToDB(item);
       }

       transaction.Complete();
   }
}

public void SaveItemToDB(object item)
{
   using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0)))
   {
       //Performing data persistency here

       transaction.Complete();
   }
}

Edit 2:

Ok, donc comme il s'avère, il y est une transaction imbriquée se passe dans la méthode 'SaveItemToDB'. Après quelques recherches dans le code d'un collègue, j'ai vu qu'elle a son propre TransactionScope défini, mais sans les options de délai d'attente et de.

Après la modification de cette méthode, de sorte qu'il a les mêmes paramètres concernant le délai d'attente, j'ai couru de nouveau le code sur le serveur du client et toujours pas de chance (encore une fois la transaction avortée d'erreur avec le temps).

Donc mes questions sont désormais comme suit:

  1. Est-il nécessaire de définir des valeurs de délai d'expiration pour les transactions imbriquées, ou font-ils héritent de ce à partir de la température ambiante de la transaction?
  2. Comment est-il possible qu'un délai d'attente d'exception peut se produire lorsque le paramètre de délai d'expiration est (sans doute, en dehors de fonctionnement interne que je ne sais pas), la même pour toutes les opérations étendues et a une valeur de délai d'expiration définie de 1 jour, lorsque l'exception se produit après environ. 10 minutes?
  3. Est-il possible de prévenir l'Oracle de la création d'une transaction distribuée pour les transactions où la connectionstring est le même?
  4. Peut-il que la charge supplémentaire d'une transaction distribuée causes des exceptions comme la transaction avortée?

J'ai mis à jour l'extrait de code de sorte qu'il reflète mieux la situation.

(btw: la deuxième, la transaction imbriquée, est nécessaire parce que le DAL aussi séparément persiste quelques éléments enfant, s'il est présent, et l'ensemble des éléments doit, bien sûr, être annulée si quelque chose va mal alors que la persistance de l'enfant les éléments)

J'espère que cette outre, il sera plus facile de faire la lumière sur cette question!

OriginalL'auteur Mace | 2010-07-14