LINQ + TransactionScope не изменит уровень изоляции в SQL Server Profiler - PullRequest
4 голосов
/ 12 октября 2010

Я использую следующий формат для передачи изменений в мою базу данных с помощью linq.

Begin Transaction (Scope Serialized, Required)
    Check Business Rule 1...N
    MyDataContext.SubmitChanges()
    Save Changes Done In Previous Query To Log File
End Transaction Scope

Но в профилировщике SQL Server я вижу следующую строку в Соединении: Пуск.

set transaction isolation level read committed

Я прошел через это (http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/93a45026-0425-4d49-a4ac-1b882e90e6d5) и подумал, что у меня есть ответ;

Пока я не увидел это (https://connect.microsoft.com/VisualStudio/feedback/details/565441/transactionscope-linq-to-sql?wa=wsignin1.0) в Microsoft Connect.

Может кто-нибудь сказать мне, действительно ли мой код выполняется на уровне Serialized Isolation Level или он действительно работает только при совершении чтения?

Ответы [ 3 ]

7 голосов
/ 21 апреля 2011

Зависит от того, как вы создали транзакцию.

Если вы запустили встроенный SQL, чтобы начать его (например, BEGIN TRAN), L2S не будет знать о транзакции и добавит новый вложенный в READ COMMITTED.

Однако, если вы использовали System.Transaction или в вашей DataContext установлена ​​транзакция, SubmitChanges будет участвовать в этой транзакции.

Эти транзакции можно запускать и останавливать в Profiler, если вы выбрали классы событий TM: Begin Tran и TM: Commit Tran.

Примечание: ADO.Net не выдает BEGIN TRAN и не выдает SET TRANSACTION ISOLATION в пакетах, это делается на более низком уровне.

Если вы действительно хотите подтвердить поведение, создайте триггер для таблицы, который вставляет текущий уровень изоляции в таблицу журналирования, и проверьте его.

Вы можете выбрать текущий уровень изоляции, выполнив:

SELECT CASE transaction_isolation_level 
WHEN 0 THEN 'Unspecified' 
WHEN 1 THEN 'Read Uncommitted' 
WHEN 2 THEN 'Read Committed' 
WHEN 3 THEN 'Repeatable Read' 
WHEN 4 THEN 'Serializable' 
WHEN 5 THEN 'Snapshot' END AS TRANSACTION_ISOLATION_LEVEL 
FROM sys.dm_exec_sessions 
where session_id = @@SPID
1 голос
/ 17 июня 2015

С http://entityframework.codeplex.com/workitem/1712

TransactionScope использует удаленные вызовы API, а не команды SQL для выполнения транзакций в SQL Server. Эти вызовы API не включены в стандартную трассировку в SQL Profiler.

Вы можете включить их, перейдя на страницу «Выбор событий», установив флажок «Показать все события» и выбрав все события из категории «Операции». Это позволит вам увидеть, когда на самом деле происходят такие события, как «TM: Begin Tran Starting», «SQLTransaction» и «TM: Begin Tran Completed».

Вы также можете проверить столбец TransactionID для событий TSQL на странице «Выбор события», чтобы увидеть, с какой транзакцией связан каждый выполняемый пакет SQL.

К сожалению, я не знаю прямого способа наблюдать эффективный уровень изоляции, при котором каждая команда выполняется в SQL Profiler. Но есть и косвенный путь ...

Когда соединение открыто, в трассировке вы увидите событие «Audit Login». Во многих случаях это событие будет содержать уровень изоляции. Теперь «Аудит входа в систему» ​​происходит до того, как установлен фактический уровень изоляции, поэтому сообщаемый уровень изоляции не будет точно отражать уровень изоляции транзакции, которая должна начаться. Вот несколько советов о том, как это интерпретировать: Когда открытие соединения действительно достигает нового соединения, оно всегда сообщает об уровне изоляции транзакции по умолчанию, например, вы увидите «установить уровень изоляции транзакции для чтения незафиксированным» (как я уже сказал, это не связано с эффективным уровнем изоляции вашей транзакции, так как он будет установлен позднее) После того, как соединение было открыто и затем возвращено в пул соединений (то есть закрыто), последующие открытия соединения будут фактически повторно использовать это существующее соединение из пула. В этом случае 'Audit Login' сообщит об уровне изоляции, который был установлен, когда соединение было возвращено в пул в последний раз. Это может помочь вам увидеть уровень изоляции, который был использован, по факту. Например. в вашем фрагменте кода соединение открыто в последний раз для отката транзакции (потому что вы не пометили транзакцию как выполненную явно). В этом событии «Audit Login» вы должны увидеть уровень изоляции, который действовал, когда соединение ранее использовалось для выполнения запроса, представленное строкой «установить уровень изоляции транзакции read uncommitted».

1 голос
/ 14 октября 2013

Полагаю, вы создали DataContext, , а затем использовали TransactionScope. Вы должны открыть соединение внутри TransactionScope, чтобы подключить его.

...