Pourquoi est-ce Système.Transactions TransactionScope default Isolationlevel Serializable
je me demande juste ce qu'est une bonne raison D'utiliser Serialisable comme le niveau d'isolation par défaut peut être lors de la création d'un le System.Transactions
TransactionScope , parce que je ne peux pas penser à tout (et il semble que vous ne pouvez pas changer la valeur par défaut via web/app.config
donc vous devez toujours le définir dans votre code)
using(var transaction = TransactionScope())
{
... //creates a Transaction with Serializable Level
}
au lieu de cela je dois toujours écrire le code de boilerplate 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?
3 réponses
Le fait Serializable
est la valeur par 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_SERIALISABLE Les données lues par une transaction en cours ne peuvent être modifié par une autre transaction jusqu'au transaction en cours terminer. Aucune nouvelle donnée ne peut être insérée qui affecterait le transaction. C'est le plus sûr niveau d'isolation par défaut, mais permet le plus bas niveau de concurrence.
.NET TransactionScope
est construit sur ces technologies.
maintenant, la question suivante est: pourquoi DTC définit ISOLATIONLEVEL_SERIALIZABLE
comme le niveau de transaction par défaut? Je suppose que C'est parce que le DTC a été conçu autour année 1995 (avant 1999 pour sûr). À cette époque, la norme SQL était SQL-92 (ou SQL2).
Et voici ce que SQL-92 dit au sujet des niveaux de transaction:
une transaction SQL a un niveau d'isolation qui est lu non engagé, Lecture engagée, répétable ou sérialisable. Le niveau d'isolation D'une transaction SQL définit le degré auquel les opérations sur SQL-données ou schémas dans cette transaction SQL sont concernés par le les effets de et peuvent affecter les opérations sur les données SQL ou les schémas dans transactions SQL simultanées. le niveau d'isolement D'une transaction SQL est sérialisable par défaut . Le niveau peut être défini explicitement par
<set transaction statement>
.l'exécution de transactions SQL simultanées au niveau d'isolement SERIALISABLE est garanti d'être serialisable. Un exe sérialisable- la persécution est défini à l'exécution des opérations de d'accord- L'exécution récente de transactions SQL qui produit le même effet que une exécution en série de ces mêmes transactions SQL. Un exe en série- cution est un dans lequel chaque transaction SQL exécute à l'achèvement avant le début de la prochaine transaction SQL.
une façon utile de réduire l'écriture de code boilerplate est de l'envelopper dans une classe de constructeur comme cela:
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);
}
}
alors vous pouvez l'utiliser comme ceci lors de la création d'un champ d'application de transaction:
using (var scope = TransactionScopeBuilder.CreateReadCommitted())
{
//do work here
}
vous pouvez ajouter d'autres paramètres de transaction communs par défaut à la classe builder comme vous en avez besoin.
Eh bien, je suppose que c'est l'un de ces "seulement le concepteur serait certainement savoir" type de questions. Mais voici mes deux cents de toute façon:
alors que le Serialisable est le niveau d'isolement le plus" limitatif " (concernant le verrouillage, dans un RDBMS basé sur le verrouillage, et donc l'accès simultané, les blocages, etc.) c'est également le niveau d'isolement le plus "sûr" (en ce qui concerne la cohérence des données).
donc, tout en ayant besoin de travail supplémentaire dans des scénarios comme le vôtre (a été là fait que ;- ), il est logique d'opter par défaut pour la variante la plus sûre. SQL Server (T / SQL) choisit d'utiliser READ COMMITTED , en appliquant évidemment d'autres raisons: -)
le rendre modifiable par configuration serait alors une mauvaise idée, car en modifiant la configuration vous pourriez rendre une application parfaitement fonctionnelle à une application cassée (parce qu'elle pourrait tout simplement ne pas être conçue pour fonctionner avec quoi que ce soit d'autre). Ou pour tourner la discussion autour, en "hardcoding" le niveau d'isolation, vous pouvez vous assurer que votre application fonctionne comme prévu. Il est permis de penser que le niveau d'isolement n'est pas un bon ajustement pour une option de configuration (alors que le "transaction timeout l'est effectivement).