Jesteśmy w trakcie stopniowego zastępowania starego kodu dostępu do danych według struktury encji (4.3.1). W niektórych przypadkach nie możemy uniknąć korzystania z obu sposobów dostępu do danych w jednej jednostce pracy. Najlepiej, żeby to się odbywało w jednej transakcji. Jednak stary kod używa SqlTransaction
s, który wywołuje Commit()
, gdy jednostka pracy jest wykonywana, a EF zarządza własnymi transakcjami.Zignoruj SqlTransaction.Commit w ramach TransactionScope
Tak więc pomyśleliśmy o zawijaniu "starego" i "nowego" kodu w TransactionScope
. Jednak zatwierdzenie w otoczeniu TransactionScope
jest zawsze wykonywane, nawet jeśli TransactionScope
nie jest ukończone. Ten fragment kodu ilustruje mój problem:
using (var conn = new SqlConnection("connection string"))
{
conn.Open();
using (var scope = new TransactionScope())
{
using (var tr = conn.BeginTransaction())
{
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tr;
cmd.CommandText = "some update statement";
cmd.ExecuteNonQuery();
}
tr.Commit();
}
// In reality the code above is part of a legacy DAL, immutable.
// (can't insert SaveChanges before tr.Commit).
context.SaveChanges();
if (<all ok>) // pseudo code for exception handling.
scope.Complete();
}
}
Oświadczenie aktualizacja jest nadal zaangażowana gdy scope.Complete()
nie jest trafiony.
Tak więc, jak się wydaje, nie mogę użyć TransactionScope
, aby wymusić stary kod dostępu do danych iz kontekstu do wykonania w jednej transakcji. A może istnieje sposób, aby uchylić instrukcję SqlTransaction.Commit?
Wiem, że jest więcej postów tutaj o TransactionScope i SqlTransaction, ale wszyscy (słusznie) twierdzą, że używanie SqlTransaction nie jest konieczne (ani zalecane) podczas korzystania z TransactionScope. Ale nie używanie SqlTransaction nie jest tutaj opcją. Mamy starszą platformę, która zatwierdza własne i nie ma api do podpięcia do mechanizmu transakcji.
Czy masz przynajmniej dostęp do połączenia? –
@LadislavMrnka Nie, oprócz ciągu połączenia w pliku konfiguracyjnym. –