Est-il possible de partager une transaction entre une application .Net et un objet COM+ ?

StackOverflow https://stackoverflow.com/questions/21589

Question

J'ai fait quelques tests il y a quelque temps et je n'ai jamais compris comment faire fonctionner cela.

Les ingrédients:

  • Objet transactionnel COM+ (développé en VB6)
  • Application Web .Net (avec transaction) dans IIS qui...
    effectue un appel au composant COM+
    met à jour une ligne dans une base de données SQL

Essai:

Exécutez l'application .Net et forcez une exception.

Résultat:

La mise à jour effectuée à partir de l'application .Net est annulée.
La mise à jour effectuée par l'objet COM+ n'est pas annulée.

Si j'appelle l'objet COM+ à partir d'une ancienne page ASP, la restauration fonctionne.

Je sais que certaines personnes peuvent penser "quoi ?!COM+ et .Net, vous devez être fou !", mais il y a des endroits dans ce monde où il y a encore beaucoup de composants COM+.J'étais juste curieux de savoir si quelqu'un avait déjà été confronté à cela et si vous aviez compris comment faire en sorte que cela fonctionne.

Était-ce utile?

La solution

Étant donné que VB et .NET utiliseront des connexions SQL différentes (et qu'il n'existe aucun moyen de faire en sorte que ADO et ADO.NET partagent la même connexion), votre seule possibilité est d'enrôler le DTC (Distributed Transaction Coordination).Le DTC coordonnera les deux transactions indépendantes afin qu'elles soient validées ou annulées ensemble.

À partir de .NET, EnterpriseServices gère les fonctionnalités COM+, telles que le DTC.Dans .NET 2.0 et versions ultérieures, vous pouvez utiliser l'espace de noms System.Transactions, ce qui rend les choses un peu plus agréables.Je pense que quelque chose comme ça devrait fonctionner (code non testé) :

void SomeMethod()
{
    EnterpriseServicesInteropOption e = EnterpriseServicesInteropOption.Full;
    using (TransactionScope s = new TransactionScope(e))
    {
        MyComPlusClass o = new MyComPlusClass();

        o.SomeTransactionalMethod();
    }
}

Je ne connais pas suffisamment cela pour vous donner plus de conseils à ce stade.

Du côté de COM+, votre objet doit être configuré pour utiliser (très probablement "exiger") une transaction distribuée.Vous pouvez le faire depuis COM+ Explorer, en accédant à la page de votre objet. Propriétés, en sélectionnant le Transaction et en cliquant sur "Requis".Je ne me souviens pas si vous pouvez également le faire à partir du code ;VB6 a été créé avant la sortie de COM+, il ne prend donc pas entièrement en charge tout ce que fait COM+ (sa prise en charge transactionnelle était destinée au prédécesseur de COM+, appelé MS Transaction Server).

Si tout fonctionne correctement, votre objet COM+ devrait s'inscrire dans le contexte existant créé par votre code .NET.

Vous pouvez utiliser le nœud « Coordinateur de transactions distribuées\Liste de transactions » dans « Services de composants » pour vérifier et voir la transaction distribuée créée lors de l'appel.

Sachez que vous ne pouvez pas voir les modifications du composant COM+ reflétées sur les requêtes de données du côté .NET tant que la transaction n'est pas validée !En fait, il est possible de se retrouver dans une impasse !N'oubliez pas que DTC s'assurera que les deux transactions sont appariées, mais qu'il s'agit toujours de transactions de base de données distinctes.

Autres conseils

Comment mettez-vous cela en œuvre ?Si vous utilisez EnterpriseServices pour gérer la transaction .NET, les deux transactions doivent être annulées, puisque vous utilisez le même contexte pour les deux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top