Was sind die Unterschiede zwischen dem klassischen Transaktionsmuster in LINQ und SQL?
using(var context = Domain.Instance.GetContext())
{
try
{
context.Connection.Open();
context.Transaction = context.Connection.BeginTransaction();
/*code*/
context.Transaction.Commit();
}
catch
{
context.Transaction.Rollback();
}
}
gegen das TransactionScope-Objekt
using (var context = Domain.Instance.GetContext())
using (var scope = new TransactionScope())
{
try
{
/*code*/
scope.Complete();
}
catch
{
}
}
quelle
Es sollte beachtet werden, dass bei Verwendung
TransactionScope
von dastry/catch
Konstrukt, das Sie haben, nicht benötigt wird . Sie müssen lediglich den Bereich aufrufenComplete
, um die Transaktion beim Beenden des Bereichs festzuschreiben.Dies
TransactionScope
ist normalerweise die bessere Wahl, da Sie damit Aufrufe an andere Methoden verschachteln können, für die möglicherweise eine Transaktion erforderlich ist, ohne den Transaktionsstatus weitergeben zu müssen.Wenn Sie
BeginTransaction
dasDbConnection
Objekt aufrufen , müssen Sie dieses Transaktionsobjekt weitergeben, wenn Sie andere Vorgänge in derselben Transaktion, jedoch mit einer anderen Methode ausführen möchten.Mit
TransactionScope
solange der Umfang existiert, wird sie alles im Griff, dass die Register mit dem aktuellenTransaction
auf dem Thread, den Code sauberer zu machen und besser wartbar.Darüber hinaus haben Sie den zusätzlichen Vorteil, dass Sie andere Ressourcen verwenden können, die an Transaktionen teilnehmen können, nicht nur die Verbindung zur Datenbank.
Es sollte beachtet werden, dass Sie in Situationen, in denen Sie Ihre Verbindungen und Datenbankoperationen optimal nutzen müssen, diese möglicherweise nicht verwenden möchten
TransactionScope
. Selbst für eine einzelne Datenbank besteht die Möglichkeit, dass der Distributed Transaction Coordinator verwendet wird und die Transaktion in eine verteilte Transaktion umgewandelt wird (auch für eine einzelne Datenbankverbindung).In diesen Fällen möchten Sie möglicherweise eine verbindungsspezifische Transaktion weitergeben, während Sie Ihr Design durcheinander bringen.
Oder , wenn Sie wissen , dass Sie eine Ressource konsequent nutzen werden (und auf dem gleichen Thread), möchten Sie vielleicht eine Klasse erstellen , die Referenz zählt Ihre Verbindung / Transaktion.
Sie würden eine Klasse erstellen, die beim Erstellen Ihre Ressource erstellt / die Anzahl erhöht. Es würde auch implementieren
IDisposable
(in dem Sie dekrementieren / freigeben / festschreiben / abbrechen würden, wenn die Anzahl Null ist) und die Anzahl in einer Variablen speichern, dieThreadStaticAttribute
auf sie angewendet wurde.Auf diese Weise können Sie die Transaktionsverwaltung vom Logikcode trennen und dennoch eine einzelne Ressource ziemlich effizient verwalten (anstatt zu einer verteilten Transaktion zu eskalieren).
quelle
Ein großer Unterschied (Lektion auf die harte Tour gelernt): TransactionScope verwendet MS DTC für das Transaktionsmanagement.
Wenn Ihre Anwendung nur Datenbanktransaktionen verwalten muss und keine Dienste oder Remoteaufrufe beteiligt sind, können Sie die potenziellen Probleme im Zusammenhang mit MS DTC überspringen, indem Sie die für Datenbanken native Transaktion (DbTransactions) verwenden.
quelle
TransactionScope
Eskaliert je nach Bedarf von einer Kernel-Transaktion zu einer DTC-Transaktion. Dies ist jedoch alles vor Ihnen verborgen. Der wichtige Punkt ist, dass dies nicht immer , sondern nach Bedarf geschieht .TransactionScope bietet eine einheitliche Verwaltung für alle Ressourcenmanager (SQL Server, Active Directory, Dateisystem usw.). Darüber hinaus kann man einen eigenen Ressourcenmanager schreiben: Code, der den Transaktionsbereich erkennt, sich diesem anschließt und genau wie SQL Server funktioniert: Änderungen wie andere Teilnehmer der Transaktion festschreiben oder zurücksetzen. Ich war der Meinung, dass TransactionScope Mainstream ist, und vergaß native MS SQL-Transaktionen, bis sie in eine große Falle gerieten: Die Windows Server 2008 WEB Edition verfügt über einen eingeschränkten Distributed Transaction Coordinator-Dienst, und der Transaktionsbereich funktioniert nur auf einem einzelnen Computer. Ihre ASP.NET-Anwendung schlägt auf diesem System fehl, wenn IIS und SQL Server auf verschiedenen Computern installiert sind. Berücksichtigen Sie, dass sich die meisten Public Domain-Anbieter, die Windows Server WEB Edition und SQL Server anbieten, auf separaten Servern befinden. Dies bedeutet, dass Sie mit nativen Transaktionen mithilfe der expliziten Transaktionsverwaltung arbeiten müssen.
quelle
Ich glaube, sie sind im Grunde die gleichen, die die TransactionScope-Klasse mit der zugrunde liegenden ADO.NET-Verbindung verbindet, um die Transaktion zu erstellen und entweder festzuschreiben oder zurückzusetzen. Die TransactionScope-Klasse wurde gerade erstellt, um die Arbeit mit ADO.NET-Persistenz sauberer zu gestalten.
Bearbeiten: Klarstellung meiner Aussage in Bezug auf die Hinzufügung von casperOne Es ist das TransactionScope, das die Transaktion erstellt, und die Verbindung sieht dann die Transaktion, die vom TransactionScope erstellt wurde, und verwendet sie, da sie verfügbar ist.
quelle