77 votes

Pourquoi System.Transactions TransactionScope est-il par défaut Isolationlevel Serializable

Je me demande simplement quelle bonne raison d’utiliser Serializable en tant que valeur par défaut pour Isolationlevel lors de la création d’un TransactionScope System.Transactions, car je ne peux en penser à aucune (et il semble que vous ne pouvez pas modifier la valeur par défaut via web / app.config afin toujours le mettre dans votre code)

 using(var transaction = TransactionScope()) {
    ... // creates a Transaction with Serializable Level
}
 

Au lieu de cela, je dois toujours écrire du code standard comme ceci:

 var txOptions = new System.Transactions.TransactionOptions();
txOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;

using(var transaction = new TransactionScope(TransactionScopeOption.Required,txOptions)) {
    ... // 
}
 

Des idées?

94voto

Simon Mourier Points 49585

Le fait Serializable est le défaut vient de l'époque où .NET n'était même pas sorti (avant l'an 1999), à partir de DTC (Distributed Transaction Coordinator) de programmation.

DTC utilise un natif ISOLATIONLEVEL énumération:

ISOLATIONLEVEL_SERIALIZABLE Les données lues par une transaction en cours ne peut pas être modifié par une autre transaction jusqu'à ce que la transaction en cours les finitions. Pas de nouvelles données peuvent être insérées qui aurait une incidence sur l'actuel des transactions. C'est le plus sûr niveau d'isolation et est la valeur par défaut, mais il permet à l'échelon le plus bas de la simultanéité.

.NET TransactionScope est construite au-dessus de ces technologies.

Maintenant, la prochaine question est: pourquoi DTC définit ISOLATIONLEVEL_SERIALIZABLE comme valeur par défaut le niveau de la transaction? Je suppose que c'est parce que la DTC a été conçu autour de l'année 1995 (avant 1999 pour être sûr). À l'époque, la Norme SQL est SQL-92 (ou SQL2).

Et voici ce que SQL-92 dit à propos des niveaux de transaction:

Un SQL-la transaction a un niveau d'isolement qui est READ UNCOMMITTED, READ committed, REPEATABLE READ, ou SERIALIZABLE. Le niveau d'isolation de un SQL-transaction définit le degré auquel les opérations sur SQL-données ou des schémas dans SQL transaction sont touchés par la effets et peuvent affecter les opérations sur SQL-données ou des schémas en simultanées SQL-transactions. Le niveau d'isolation d'un SQL - transaction est SÉRIALISABLE par défaut. Le niveau peut être explicitement défini par le .

L'exécution de SQL simultanées-transactions au niveau d'isolation SERIALIZABLE est garanti d'être sérialisable. Un serializable exe- la persécution est défini à l'exécution des opérations de concourir- actuellement l'exécution de SQL-transactions qui produit le même effet que certains d'exécution en série de ces mêmes SQL-transactions. Une série exe- la persécution est celui dans lequel chaque SQL-transaction exécute à la réalisation avant la prochaine SQL-transaction commence.

52voto

Almond Points 901

Un moyen utile de réduire l’écriture du code standard consiste à l’envelopper dans une classe de générateur comme ceci:

   public static class TransactionScopeBuilder
  {
    /// <summary>
    /// Creates a transactionscope with ReadCommitted Isolation, the same level as sql server
    /// </summary>
    /// <returns>A transaction scope</returns>
    public static TransactionScope CreateReadCommitted()
    {
        var options = new TransactionOptions
            {
                IsolationLevel = IsolationLevel.ReadCommitted,
                Timeout = TransactionManager.DefaultTimeout
            };

        return new TransactionScope(TransactionScopeOption.Required, options);
    } 
}
 

Vous pouvez ensuite l'utiliser comme ceci lors de la création d'une étendue de transaction:

     using (var scope = TransactionScopeBuilder.CreateReadCommitted())
    {
        //do work here
    }
 

Vous pouvez ajouter d'autres valeurs d'étendue de transaction courantes par défaut à la classe de générateur selon vos besoins.

29voto

Christian.K Points 18883

Eh bien, je suppose que c'est un de ces "seul le concepteur devrait certainement savoir" type de questions. Mais voici mes deux cents, de toute façon:

Alors que Serializable est le plus "limite" niveau d'isolation (concernant le verrouillage, dans une serrure à base de SGBDR, et donc l'accès simultané, blocages, etc.) il est aussi le plus "safe" niveau d'isolation (concernant la cohérence des données).

Donc, bien que nécessitant un travail supplémentaire dans les scénarios comme la vôtre (été là ; -), - il judicieux d'opter pour la plus sûre de la variante par défaut. SQL Server (T/SQL) choisit d'utiliser READ committed, évidemment, de l'application d'autres raisons :-)

Rendre modifiable par configuration, serait une mauvaise idée, parce qu'en jouant avec la configuration que vous pourrait rendre parfaitement de travail de l'application d'une fracture de l'un (parce qu'il peut tout simplement pas conçu pour fonctionner avec n'importe quoi d'autre). Ou pour l'éteindre, l'argument autour de, par "le coder en dur", le niveau d'isolation, vous pouvez vous assurer que votre application fonctionne comme prévu. Sans doute, le niveau d'isolement n'est pas un bon ajustement pour une option de configuration (alors que le délai d'expiration de transaction est en effet).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X