LINQ и TranscationScope не работают

Я использую оператор выбора LINQ, заключенный в TransactionScope (для изменения блокировки), но, согласно SQL Profiler, он, похоже, не работает. Мой код выглядит так:

using (var ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted} ))
{
   using (myDBDataContext dbPKC = new myDBDataContext(conn))
   {
      ...query...
      ts.Complete();
      return xmlMachine;
   }
}

Теперь я ожидаю, что SQL Profiler покажет BatchStarting и BatchComplete для моего оператора select. Но он показывает RPC: Completed. Почему? когда я запускаю этот код:

using (SqlConnection conn1 = new SqlConnection())
    {
      conn1.ConnectionString = WebConfigurationManager.ConnectionStrings["myConnectionString"].ToString(); ;
      conn1.Open();
      using (SqlTransaction trans1 = conn1.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
      {
        SqlCommand cmd = new SqlCommand("select * from Machines where pkID = 5");
        cmd.Connection = conn1;
        cmd.Transaction = trans1;
        SqlDataReader reader = cmd.ExecuteReader(); // just execute something
      }
    }

Он показывает BatchStarting и BatchComplete. Почему кажется, что LINQ «не видит» TransactionScope?

Также есть способ подтвердить, что мой уровень изоляции правильный с помощью Profiler? Я могу видеть только начальный уровень изоляции соединения через Audit Login. «Обновление» не отображается, чтобы показать, что оно было изменено или какой уровень изоляции используется в каждом запросе.

Любая помощь будет замечательной!

Кроме того, этот код работает в службе WCF (3.5), подключающейся к SQL Server 2008.


person BabelFish    schedule 02.09.2010    source источник
comment
Почему вы используете область транзакции для запроса?   -  person garik    schedule 03.09.2010
comment
Ищите УСТАНОВИТЬ УРОВЕНЬ ИЗОЛЯЦИИ СДЕЛКИ   -  person garik    schedule 03.09.2010
comment
Я использую transactioncope, чтобы изменить тип блокировки. Я делаю эквивалент оператора выбора nolock. Я использую linq, потому что я делаю оператор выбора и помещаю его в xml в той же строке. (XElement)   -  person BabelFish    schedule 03.09.2010
comment
Уровень изоляции транзакции - это то, что я пытаюсь изменить :) Я гуглил это уже несколько часов. :)   -  person BabelFish    schedule 03.09.2010
comment
Попробуйте проверить уровень изоляции, действительно ли он изменился или нет .. Я обновил свой ответ   -  person garik    schedule 03.09.2010
comment
Только один из вариантов уровня изоляции может быть установлен за раз, и он остается установленным для этого соединения до тех пор, пока не будет изменен явным образом. Все операции чтения, выполняемые в рамках транзакции, выполняются в соответствии с правилами для указанного уровня изоляции, если табличная подсказка в предложении FROM оператора не указывает другое поведение блокировки или управления версиями для таблицы. msdn.microsoft.com/en-us/library/ ms173763% 28SQL.90% 29.aspx   -  person garik    schedule 03.09.2010
comment
см. примечания на этой странице ... эскалация блокировки ...   -  person garik    schedule 03.09.2010


Ответы (1)


ОБНОВЛЕНО:

Попробуйте что-нибудь вроде этого, чтобы проверить уровень изоляции:

using(TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, options))
{
    //Verify Scope using DBCC USEROPTIONS
    SqlCommand cmd = (SqlCommand)ctxt.Connection.CreateCommand();
    cmd.CommandText = "DBCC USEROPTIONS";
    SqlDataReader r = cmd.ExecuteReader();
    while (r.Read())
    {
        Console.WriteLine(r.GetValue(0) + ":" + r.GetValue(1));
    }
}   

ДОБАВЛЕНО:

Ищите SET TRANSACTION ISOLATION LEVEL

person garik    schedule 02.09.2010
comment
переключение порядка (создание экземпляра db, затем транскопе) по-прежнему показывает RPC: Completed :( - person BabelFish; 02.09.2010
comment
спасибо .. похоже, что transcope работает .. профилировщик должен отображать операторы SP, потому что linq выполняет sql через sq_executesql и показывает операторы TM для отображения того, что транзакции выполняются. ваш код также помог показать, что уровень изоляции правильный. TextSize: -1 язык: us_english dateformat: mdy datefirst: 7 lock_timeout: -1 quoted_identifier: SET ansi_null_dflt_on: SET ansi_warnings: SET ansi_padding: SET ansi_nulls: SET concat_null_yields_null: SET уровень изоляции: чтение uncommitted - person BabelFish; 03.09.2010
comment
Это приводит к моим следующим вопросам. Этот оператор выбора заблокирован другой транзакцией, использующей readcommited. почему этот оператор select был заблокирован? два вызова работают с одними и теми же таблицами, но с разными строками. у обоих вызовов есть большие предложения where, если это имеет значение. - person BabelFish; 03.09.2010
comment
@BabelFish Одновременно можно установить только один из параметров уровня изоляции, и он остается установленным для этого соединения до тех пор, пока не будет явно изменен. Все операции чтения, выполняемые в рамках транзакции, выполняются в соответствии с правилами для указанного уровня изоляции, если табличная подсказка в предложении FROM оператора не указывает другое поведение блокировки или управления версиями для таблицы. msdn.microsoft.com/en-us/library/ ms173763% 28SQL.90% 29.aspx - person garik; 03.09.2010
comment
да, чтобы уточнить. их две разные транзакции. Похоже, что происходит то, что tran1 выполняет длинный процесс обновления строки из таблицы X, которая блокирует оператор select tran2 до таблицы X. Не уверен, почему, поскольку оператор select tran2 в основном TableX.Single (x = ›x.pkID = 14); Разве этот оператор не должен без проблем найти точную строку, если tran1 НЕ касается строки 14? изменение изоляции на readuncommited для tran2 решает одну проблему, но почему readcommitted недостаточно, если мой выбор основан на первичном ключе? tran1 использует readcommitted. еще раз спасибо! - person BabelFish; 03.09.2010