Мы находимся в процессе постепенной замены устаревшего кода доступа к данным структурой сущностей (4.3.1 ). В некоторых случаях мы не можем избежать использования обоих способов доступа к данным в одной единице работы. В идеале это должно быть сделано за одну транзакцию. Однако старый код использует SqlTransaction
, которые вызывают Commit()
, когда выполняется единица работы, а EF управляет своими транзакциями.
Поэтому мы подумали о заключении «старого» и «нового» кода вTransactionScope
. Однако фиксация внутри окружения TransactionScope
всегда выполняется, даже если TransactionScope
не завершен. Этот фрагмент кода иллюстрирует мою проблему:
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 () // pseudo code for exception handling.
scope.Complete();
}
}
Оператор обновления по-прежнему фиксируется , когда scope.Complete()
не срабатывает.
Итак, похоже, я не могу использовать TransactionScope
, чтобы заставить старый код доступа к данным и SaveChanges
из контекста выполняться в одной транзакции. Или есть способ переопределить оператор SqlTransaction.Commit?
Я знаю, что здесь есть еще сообщения о TransactionScope и SqlTransaction, но все они (справедливо )говорят, что использование SqlTransaction не является необходимым (и не рекомендуется )при использовании TransactionScope.Но не использовать SqlTransaction здесь нельзя. У нас есть устаревший фреймворк, который фиксирует свои собственные SqlTransaction
s и не имеет API для подключения к механизму транзакций.