9
votes

Confusion sur les transactions et MSDTC

J'ai une certaine confusion de base sur la manière dont les transactions et la MSDTC travaillent ensemble.

J'ai une application de base du serveur / client WinForms. L'application utilise des transactions pour encapsuler plusieurs commandes SQL exécutées sur le serveur SQL.

L'application semblait fonctionner correctement lorsque j'ai activé l'accès réseau MSDTC sur le serveur uniquement. Puis un jour, il a cessé de travailler dire que l'accès au réseau n'a pas été activé.

Maintenant, il semble que je dois activer l'accès au réseau MSDTC sur l'ordinateur client et le serveur pour que les transactions fonctionnent.

Le service client ou serveur MSDTC fait-il le travail de transaction? Ou peut-être que c'est les deux?

Quelqu'un a-t-il des conseils sur le fait que l'accès réseau MSDTC est nécessaire sur le client et le serveur ou simplement serveur?


0 commentaires

3 Réponses :


11
votes

Si vous utilisez MSDTC, vous aurez besoin du client (votre application) et du serveur (base de données) pour exécuter MSDTC et également à être configuré correctement.

Cela peut être source de douleur, en particulier lorsqu'il s'agit de pare-feu. Si vous rencontrez des problèmes, voir Problèmes de dépannage avec MSDTC . Il parle de biztalk mais il s'applique à MSDTC en général. dtcping est également votre ami .

Maintenant, si vous utilisez SQL Server 2005 et plus haut, vous accédez à une seule base de données, utilisez une connexion de base de données et ne transmettez pas de transactions entre les domaines de l'application, vous ne devez pas nécessiter l'utilisation de MSDTC. Dans ces circonstances, le System.Transactions Transaction Manager gérera vos transactions pour vous. Si l'une des situations précédentes survient, la transaction sera promue à une transaction distribuée (et le gestionnaire de transactions sera MSDTC). Voir escalade de gestion des transactions pour plus d'informations.

En général, il est préférable d'éviter l'utilisation de MSDTC si vous n'en avez pas besoin. I.e. Si vous ne faites que traiter avec une seule base de données SQL Server 2005++, essayez de concevoir votre code pour ne pas utiliser MSDTC. Outre le tracas de configuration, le DTC impose une pénalité de performance car tous les appels vers MSDTC sont hors de trait combinés avec les frais généraux du protocole de validation de deux phases (qui utilise MSDTC).

En termes de ce qui se passe dans votre situation spécifique, il est difficile de dire. Si votre code n'a pas changé, les règles de pare-feu ont-elles changé? J'ai également vu des mises à jour de Windows modifier la configuration DTC (pour la sécurité) qui a provoqué un problème.

mise à jour basée sur le commentaire:

Pour surveiller la promotion de la transaction ou l'escalade, si vous n'utilisez aucune transaction distribuée, je pense que vous pouvez utiliser certains des compteurs de performance du coordonnateur de transactions distribuées pour suivre les transactions engagées. Si vous testez, vous pouvez désactiver MSDTC et voir si votre code échoue. Une autre façon serait de surveiller les transactions dans SQL Server. A partir d'une perspective de codage, vous pouvez essayer de gérer le DistributedTransactionStarté événement et faire une journalisation (mais supprimez ce code avant d'aller à la production).

Pour un exemple de code à l'aide d'une connexion unique, accédez au transactionscope page à MSDN. Fondamentalement, créez un transaction de transaction, créez une SQLConnection, faites-le de travail avec la SQLConnection, fermez la connexion, appelez Scope.comPlete ().

Notez que si vous utilisez des méthodes d'adaptateur de données, ils gèrent automatiquement votre connexion afin que la connexion soit fermée ou renvoyée au pool de connexion. De toute façon, si une autre opération est appelée, la transaction sera promue à une transaction DTC. Voir System.Transactions et connexion Foo communing pour plus de détails.


1 commentaires

Merci pour la superbe info. J'aimerais ne pas utiliser MSDTC. J'utilise SQL2005, 1 dB, ne pas passer des domaines d'application, mais pas sûr que j'utilise 1 connexion. Serait-il possible de donner un court exemple de transaction avec plusieurs déclarations SQL qui ne seraient pas élevées à la DTC? Existe-t-il un outil ou un autre moyen de dire si mes transactions sont enlevées à MSDTC?



8
votes

Pour développer l'explication de @ Tuzo, voici un exemple de commande qui va toujours escalader: xxx pré>

dans la pratique, la connexion et la commande seront dans une autre classe, etc., mais vous avez eu l'idée. Même si la chaîne de connexion est sur la même base de données, elle augmentera à l'aide de la DTC, car il s'agit de deux connexions. Une transaction non escalade serait la suivante: p> xxx pré>

C'est un meilleur code de toute façon, car vous ouvrez la connexion, faites ce dont vous avez besoin et fermez le plus tôt possible. Cela signifie que vous devez réfléchir à votre gestion de connexion. Selon votre application, vous pouvez la mettre en œuvre différemment. Par exemple: P>

using(var scope = new TransactionScope())
using(var conn = new SqlConnection(connString))
{
    conn.Open();
    var myService = new MyService(conn);
    var myService2 = new MyService2(conn);
    myService.DoSomething();
    myService2.DoSomething();
    scope.Complete();
}


2 commentaires

Bloc d'accès aux données de la bibliothèque d'entreprise peut aider car il conserve une liste interne des transactions actives et de leurs connexions (dans la classe de transactionsCopeconnections). La même connexion est utilisée pour la durée de vie de la transaction de sorte que la transaction ne s'algroupe pas vers une transaction distribuée. Il bénéficie également de la fabrication de vos interfaces Nettoyant car vous n'avez pas besoin de transmettre la connexion sur chaque méthode nécessaire pour utiliser une connexion de base de données.


Pour les utilisateurs de SQLSERVER 2008: le premier exemple de votre code n'alcalera pas sur SQLServer 2008. Il ne fermez que si vous ne fermez pas la première connexion avant d'ouvrir le second (par exemple, si vous niez la 3ème étape par Stament à l'aide de la 2e relevé ).



0
votes

Mise à jour: J'ai trouvé un article qui explique pourquoi les transactions sont en cours de promotion de la formulaire LTM à MSDTC lorsqu'ils utilisent uniquement GetData et Mettre à jour sur le même adaptateur de données dans un transaction de transaction avec une solution de contournement.

Transactions de blog Post http: //blah.winsmarts .COM / 2006/06/18 / the-définitif-tableadapters - transactions-blog-post.aspx p>

Je comprends la partie à propos de plusieurs connexions ouvertes à une fois augmenter une transaction pour être distribué. Cependant, je rencontre un problème où il n'y a qu'une seule connexion et une requête contre une base de données qui l'escalade. Il n'y a aucune transaction dans la procédure stockée non plus. Si quelqu'un a un indice, j'aimerais en entendre. De mon exemple de code, "l'adaptateur.update (tableau)" déclenchera une transaction distribuée. P>

J'ai apporté le courage du code de mon projet existant et simplifié la plupart de ce qui se passait, et j'ai toujours les mêmes problèmes. Cela crée essentiellement un jeu de données avec un adaptateur de table et la configurant avec une procédure stockée pour sélectionner, insérer et supprimer. Je sélectionne tous les enregistrements associés à un utilisateur spécifique. Ensuite, en fonction de si un "myppid" existe pour l'un des enregistrements, je l'ajoute ou le supprimez. J'appelle ensuite la méthode de mise à jour et je vois que la transaction augmente pour être distribuée en regardant les statistiques de transaction dans les services des composants. P>

J'utilise Windows XP Pro SP3 et .NET Framework 3.5 pour le programme client. Il se connecte à une base de données SQL 2005 sur le LAN à Windows Server 2003 R2 Enterprise Edition SP2. P>

ALTER procedure [dbo].[p_UserForm_AssignedPP_Delete]
(
    @Original_UserId INT,
    @Original_MyPPId INT
)
AS
SET NOCOUNT ON;
DELETE FROM usermypp WHERE [UserID] = @Original_UserId 
    AND [MyPPID] = @Original_MyPPId


0 commentaires