Transaction scope vs Transaction in LINQ to SQL

Quelles sont les différences entre le classique motif de transaction dans LINQ to SQL comme:

using(var context = Domain.Instance.GetContext())
{
    try
    {
        context.Connection.Open();
        context.Transaction = context.Connection.BeginTransaction();
        /*code*/
        context.Transaction.Commit();
    }
    catch
    {
        context.Transaction.Rollback();
    }         
}

vs l'objet TransactionScope

using (var context = Domain.Instance.GetContext())
using (var scope = new TransactionScope())
{
    try
    {
        /*code*/
        scope.Complete();
    }
    catch
    {
    }
}
74
demandé sur abatishchev 2009-02-12 20:50:23

5 réponses

Linq2SQL utilisera une transaction implicite. Si toutes vos mises à jour sont effectuées au sein d'un même envoi, vous n'aurez peut-être pas besoin de gérer la transaction vous-même.

à Partir de la documentation (l'emphase est mienne):

lorsque vous appelez SubmitChanges, LINQ to SQL vérifie si l'appel est dans le cadre d'une Transaction ou si la propriété de la Transaction (IDbTransaction) est définie à une transaction locale initialisée par l'utilisateur. S'il trouve ni l'une ni l'autre des transactions, LINQ to SQL démarre une transaction locale (IDbTransaction) et l'utilise pour exécuter les commandes SQL générées. lorsque toutes les commandes SQL ont été exécutées avec succès, LINQ to SQL engage la transaction locale et renvoie.

34
répondu TGnat 2011-10-04 12:08:02

il est à noter que lors de l'utilisation du TransactionScope il n'est pas nécessaire pour le try/catch construction que vous avez. Il suffit d'appeler Complete sur le périmètre pour engager la transaction lorsque le périmètre est sorti.

cela étant dit, TransactionScope est généralement un meilleur choix parce qu'il vous permet de faire des appels vers d'autres méthodes qui pourraient nécessiter une transaction sans que vous ayez à passer l'état des transactions autour de.

lorsque vous appelez BeginTransaction sur l'objet DbConnection , vous devez passer cet objet de transaction si vous voulez effectuer d'autres opérations dans la même transaction, mais selon une méthode différente.

avec TransactionScope , aussi longtemps que la portée existe, il traitera tout ce qui est enregistré avec le courant Transaction sur le fil, ce qui rend votre code plus propre, et plus maintenable.

en plus de cela, vous avez l'avantage supplémentaire d'être en mesure d'utiliser d'autres ressources qui peuvent participer à des transactions, pas seulement la connexion à la base de données.

il est à noter que dans les situations où vous avez besoin de tirer le maximum de vos connexions et opérations de base de données, vous pourriez ne pas vouloir utiliser TransactionScope ; même contre une seule base de données, vous exécutez la possibilité de le Coordonnateur des transactions distribuées est utilisé et la transaction est transformée en une transaction distribuée (même pour une seule connexion à la base de données).

dans ces cas, tout en brouillant votre conception, vous pourriez envisager de passer une transaction spécifique à la connexion.

Ou , si vous savez que vous allez utiliser une ressource constante (et sur le même sujet), vous pouvez créer une classe qui référence-compte votre connexion / transaction.

vous créeriez une classe qui sur la construction, crée votre ressource/augmente le nombre. Elle mettrait également en œuvre IDisposable (dans lequel vous décrémenteriez/relâcheriez/commiteriez/avorter quand le nombre est zéro), et stocker le nombre dans une variable qui a ThreadStaticAttribute appliquée à elle.

Cela vous permet de séparer la gestion des transactions de le code logique, et toujours tenir sur une ressource singulière assez efficacement (au lieu d'escalader à une transaction distribuée).

72
répondu casperOne 2012-01-31 18:56:23

une grande différence – leçon apprise à la dure) - Transactionsscope utilise MS DTC pour la gestion des transactions.

si votre application doit gérer la transaction de base de données seulement, et aucun service ou appel à distance sont impliqués, vous pouvez sauter les problèmes potentiels liés à MS DTC en utilisant la transaction native aux bases de données (DbTransactions).

20
répondu Mayank 2011-10-04 22:52:42

Transactionsscope fournit une gestion unifiée pour tous les gestionnaires de ressources (serveur SQL, active directory, système de fichiers, ...). De plus, on peut écrire own resource manager: code qui détecte la portée de la transaction, la rejoindre et fonctionne exactement comme SQL server: COMMIT ou inverse les changements comme les autres participants de la transaction. J'ai cru que TransactionScope est grand public et oublié MS SQL transactions natives jusqu'à échoué dans le piège énorme: Windows Server 2008 Web Edition comes avec le service de coordonnateur des transactions distribuées restreintes, le service et la portée des transactions ne fonctionnent que sur un seul ordinateur. Votre ASP.NET application échouera sur ce système si IIS et SQL server sont installés sur des ordinateurs différents. Prenez en compte que la plupart des fournisseurs de domaine public fournissant Windows Server WEB edition et SQL server sont sur des serveurs séparés. Cela signifie que vous devez travailler avec les transactions natives en utilisant la gestion explicite des transactions ...

6
répondu Gediminas Bukauskas 2012-05-18 13:39:19

je crois qu'ils sont fondamentalement les mêmes que la classe TransactionScope sera interface avec le ADO.NET connexion sous-jacente pour créer et soit propager ou annuler la transaction. Que la classe TransactionScope a juste été créée pour faire travailler avec ADO.NET nettoyant de persistance.

Edit: Clarifier mon intervention, en ce qui concerne casperOne est plus c'est la TransactionScope qui permettra de créer le transaction et la connexion sera alors voir la transaction, qui a été créé par le TransactionScope et de l'utiliser car il est disponible.

4
répondu Chris Marisic 2017-05-23 12:25:36