Kann ich einen Verweis auf eine ausstehende Transaktion von einem SqlConnection-Objekt abrufen?
Angenommen, jemand (außer mir) schreibt den folgenden code und kompiliert ihn in eine assembly:
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (var transaction = conn.BeginTransaction())
{
/* Update something in the database */
/* Then call any registered OnUpdate handlers */
InvokeOnUpdate(conn);
transaction.Commit();
}
}
Den Aufruf InvokeOnUpdate(IDbConnection conn) ruft einen event-handler, kann ich implementieren und registrieren. So, in diesem hf habe ich einen Verweis auf die IDbConnection-Objekt, aber ich nicht ein Verweis auf die ausstehende Transaktion. Gibt es eine Möglichkeit, in denen ich einen halt bekommen können von der Transaktion? In meinem OnUpdate-handler, die ich ausführen möchten etwas ähnlich dem folgenden:
private void MyOnUpdateHandler(IDbConnection conn)
{
var cmd = conn.CreateCommand();
cmd.CommandText = someSQLString;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
Jedoch der Aufruf von cmd.ExecuteNonQuery() wirft eine InvalidOperationException beschwert, dass
"ExecuteNonQuery erfordert der Befehl
eine Transaktion, wenn die
Verbindung dem Befehl zugewiesen ist
in einem anhängigen lokale Transaktion. Die
Transaktion-Eigenschaft des command -
wurde nicht initialisiert".
Kann ich in keiner Weise gewinnen meine SqlCommand cmd mit der anstehenden Transaktion? Kann ich abrufen, einen Verweis auf die ausstehende Transaktion von der IDbConnection-Objekt (ich würde gerne reflektion verwenden, wenn nötig)?
InformationsquelleAutor der Frage Rune | 2009-01-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wow ich wusste nicht, hoffen diese auf den ersten. Ich bin überrascht, dass CreateCommand() gibt nicht den Befehl, die Transaktion, wenn die Verwendung lokaler SQL-Server-Transaktionen, und, dass die Transaktion nicht ausgesetzt, auf das SqlConnection-Objekt. Tatsächlich, wenn die Reflexion auf das SqlConnection-die aktuelle Transaktion ist nicht einmal gespeicherte Objekt. In der edit ist unten, ich gab Ihnen einige Hinweise, um die Spur des Objekts über einige Ihrer internen Klassen.
Ich weiß, Sie können nicht ändern die Methode aber könnte Sie eine TransactionScope-rund um die Methode bar? Also, wenn Sie haben:
Dies funktioniert, getestet habe ich mit ähnliche code zu verkaufen und sobald ich die wrapper-alle funktioniert gut, wenn Sie können dies tun, natürlich. Wie schon darauf achten, wenn mehr als eine Verbindung geöffnet ist bis in die TransactionScope-Sie eskaliert werden, um eine Verteilte Transaktion, die, sofern Sie Ihr system so konfiguriert ist, dass Sie erhalten Sie eine Fehlermeldung.
Eintragen mit dem DTC ist auch um ein Vielfaches langsamer als eine lokale Transaktion.
Bearbeiten
wenn Sie wirklich wollen, um zu versuchen und verwenden Sie reflektion, SqlConnection hat eine SqlInternalConnection dies wiederum hat eine Eigenschaft AvailableInternalTransaction gibt eine SqlInternalTransaction, diese hat eine Eigenschaft " Parent gibt das SqlTransaction-Sie brauchen würde.
InformationsquelleAutor der Antwort JoshBerke
Falls jemand interessiert ist, in der Reflexion-code, um dies zu erreichen, geht es hier:
Hinweise:
InformationsquelleAutor der Antwort Alvaro Rodriguez
Für jeden, der interessiert ist, die C# - version des decorator-Klasse, Denis made in VB.NET hier ist es:
InformationsquelleAutor der Antwort victorvartan
Den Befehl Objekt können nur zugeordnet werden, ein transaction-Objekt mit einer der Konstruktoren. Sie können gehen für den .NET 2.0-Ansatz und verwenden Sie eine TransactionScope-Objekt, das definiert ist in der
System.Transactions
namespace (hat eine eigene assembly).System.Transaktionen Ansatz verwendet, in Verbindung mit SQL-Server 2005 eine leichte transaction coordinator (LTM). Seien Sie vorsichtig, nicht zu verwenden Sie mehrere connection-Objekte in der Transaktion Umfang oder die Transaktion wird befördert, als es ist gesehen als verteilt. Diese mehr Ressourcen-intensive version der Transaktion wird der dann gehandhabt werden, DTC.
InformationsquelleAutor der Antwort lvaneenoo
Ich bin ein großer Verfechter von einfachen, so wie über das schreiben eines wrappers über IDBConnection (DELEGATE-PATTERN) , stellt die Transaktion. (Sorry für VB.NET code Schreibe ich dieses in VB.NET jetzt) so Etwas wie dieses:
So würden Sie instanziieren Sie diese als:
, und dann können Sie die Transaktion zu jeder Zeit:
InformationsquelleAutor der Antwort Denis
In Fällen, In denen jemand konfrontiert dieses problem auf .Net 4.5, die Sie verwenden können
Transaction.Current
in
System.Transactions
.InformationsquelleAutor der Antwort A77