EF 4.1 - Хранимая процедура не наследует ожидающую транзакцию - PullRequest
2 голосов
/ 19 января 2012

У меня есть интеграционный тест, который выглядит следующим образом:

using (var tran = Connection.BeginTransaction(IsolationLevel.ReadUncommitted))
{
   try
   {
      // Act.
      var result = controller.Create(something);

      // Assert.
      Assert.IsNotNull(result);
   }
   catch (Exception exc)
   {
      Assert.Fail(exc.Message);
   }
   finally
   {
      tran.Rollback();
      Connection.Close();
   }
}

Теперь в этом методе Create я в итоге вызываю хранимую процедуру, которая возвращает несколько наборов результатов.

Вот код для вызова этого SP:

var cmd = Database.Connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "exec dbo.MySP @SomeParam";
cmd.Parameters.Add(new SqlParameter { Value = "test", ParameterName = "SomeParam" });

using (var rdr = cmd.ExecuteReader()) <--- exception thrown here.
{
   // code to read result sets.
}

Я получаю следующее исключение:

System.InvalidOperationException: ExecuteReader требует, чтобы команда имелатранзакция, когда соединение, назначенное команде, находится в ожидающей локальной транзакции.Свойство Transaction команды не было инициализировано.

Что, я думаю, имеет смысл, но я бы подумал, что оно унаследует ожидающую локальную транзакцию?

Ранее у меня был вышеуказанный код, открывающий новое соединение, но оно просто истекло из-за явной блокировки ожидающей транзакции на определенных таблицах, несмотря на уровень изоляции непринятого чтения.

В основномМне нужно иметь возможность провести интеграционный тест, который:

  1. Открывает транзакцию
  2. Делает некоторые вещи, в том числе сохраняет некоторые записи в БД, затем вызывает другую хранимую процедуру, которая обращается кданные, которые включают вновь созданные данные
  3. Откат транзакции.

Любые идеи, ребята?

1 Ответ

1 голос
/ 20 января 2012

Это работает:

using (new TransactionScope(TransactionScopeOption.Required, 
   new TransactionOptions 
   { 
      IsolationLevel = IsolationLevel.ReadUncommitted
   }))

Это не:

using (var tran = Connection.BeginTransaction(IsolationLevel.ReadUncommitted))
{

Должен иметь какое-то отношение к тому факту, что TransactionScope живет вне фактического Соединения, поэтому он оборачивает все соединения, которые открыты внутри него, в то время как предыдущий код открывает транзакцию с определенным подключение.

...