Ich frage mich nur, was ein guter Grund für die Verwendung von Serializable als Standard-Isolationsstufe beim Erstellen eines System.Transactions TransactionScope sein kann , da mir keine einfällt (und es scheint, dass Sie die Standardeinstellung über nicht ändern können, web/app.config
sodass Sie sie immer festlegen müssen dein Code)
using(var transaction = TransactionScope())
{
... //creates a Transaction with Serializable Level
}
Stattdessen muss ich immer Boilerplate-Code wie folgt schreiben:
var txOptions = new System.Transactions.TransactionOptions();
txOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
using(var transaction = new TransactionScope(TransactionScopeOption.Required, txOptions))
{
...
}
Irgendwelche Ideen?
c#
transactionscope
isolation-level
Bernhard Kircher
quelle
quelle
Antworten:
Tatsache
Serializable
ist, dass die Standardeinstellung aus Zeiten stammt, in denen .NET noch nicht einmal (vor dem Jahr 1999) aus der DTC- Programmierung ( Distributed Transaction Coordinator ) veröffentlicht wurde.DTC verwendet eine native ISOLATIONLEVEL- Aufzählung:
.NET
TransactionScope
basiert auf diesen Technologien.Die nächste Frage lautet nun: Warum wird DTC
ISOLATIONLEVEL_SERIALIZABLE
als Standardtransaktionsstufe definiert ? Ich nehme an, das liegt daran, dass DTC um das Jahr 1995 herum entworfen wurde (sicher vor 1999). Zu dieser Zeit war der SQL-Standard SQL-92 (oder SQL2).Und hier ist, was SQL-92 über Transaktionsebenen sagt:
quelle
Ein nützlicher Weg, um das Schreiben von Boilerplate-Code zu reduzieren, besteht darin, ihn in eine Builder-Klasse wie folgt zu verpacken:
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); } }
Dann können Sie es beim Erstellen eines Transaktionsbereichs folgendermaßen verwenden:
using (var scope = TransactionScopeBuilder.CreateReadCommitted()) { //do work here }
Sie können der Builder-Klasse nach Bedarf weitere allgemeine Standardeinstellungen für den Transaktionsbereich hinzufügen.
quelle
Nun, ich denke, dies ist eine dieser Fragen, die "nur der Designer definitiv kennen würde". Aber hier sind trotzdem meine zwei Cent:
Serializable ist zwar die "einschränkendste" Isolationsstufe (in Bezug auf das Sperren, in einem sperrbasierten RDBMS und damit gleichzeitigen Zugriff, Deadlocks usw.), aber auch die "sicherste" Isolationsstufe (in Bezug auf die Datenkonsistenz).
Während in Szenarien wie Ihren zusätzliche Arbeit erforderlich ist (wurde dies bereits getan ;-), ist es sinnvoll, standardmäßig die sicherste Variante zu wählen. SQL Server (T / SQL) verwendet READ COMMITTED aus anderen Gründen :-)
Es wäre dann eine schlechte Idee, es durch Konfiguration veränderbar zu machen, da Sie durch Fummeln an der Konfiguration eine perfekt funktionierende Anwendung in eine defekte umwandeln könnten (weil sie möglicherweise einfach nicht für die Verwendung mit irgendetwas anderem ausgelegt ist). Um das Argument umzukehren, können Sie durch "Hardcodierung" der Isolationsstufe sicherstellen, dass Ihre Anwendung wie erwartet funktioniert. Die Isolationsstufe passt wahrscheinlich nicht zu einer Konfigurationsoption (während das Transaktionszeitlimit tatsächlich ist).
quelle