4

我使用以下格式使用 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 探查器中,我在 Connection:Start 中看到以下行。

set transaction isolation level read committed

我经历了这个(http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/93a45026-0425-4d49-a4ac-1b882e90e6d5)并认为我有答案;

直到我在 Microsoft Connect 上看到这个(https://connect.microsoft.com/VisualStudio/feedback/details/565441/transactionscope-linq-to-sql?wa=wsignin1.0)。

有人可以告诉我我的代码实际上是在序列化隔离级别下执行的,还是实际上只是在读取提交下运行?

4

3 回答 3

7

这取决于您如何创建交易。

如果您执行内联 SQL 来开始它(例如BEGIN TRAN),L2S 将不知道该事务并将在READ COMMITTED.

但是,如果您使用 System.Transaction,或者在您的 上设置了事务DataContext,则 SubmitChanges 将参与该事务。

如果您选择TM: Begin TranTM: Commit Tran事件类,您可以在 Profiler 中看到这些事务的开始和停止。

注意: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
于 2011-04-21T11:38:33.440 回答
1

我的猜测是您创建了 DataContext,然后使用了 TransactionScope。您必须在TransactionScope 中打开连接才能使其登记。

于 2013-10-14T16:25:06.213 回答
1

来自http://entityframework.codeplex.com/workitem/1712

TransactionScope 使用远程 API 调用而不是 SQL 命令在 SQL Server 中执行事务。这些 API 调用不包含在 SQL Profiler 的标准跟踪中。

您可以通过转到“事件选择”页面,单击“显示所有事件”复选框并从“事务”类别中选择所有事件来包含它们。这将允许您查看诸如“TM: Begin Tran Starting”、“SQLTransaction”和“TM: Begin Tran Completed”之类的事件实际发生的时间。

您还可以在“事件选择”页面中检查 TSQL 事件的 TransactionID 列,以查看每个正在执行的 SQL 批处理与哪个事务相关联。

不幸的是,我不知道一种直接的方法来观察在 SQL Profiler 中执行每个命令的有效隔离级别。但是有一个间接的方法...

打开连接后,您将在跟踪中看到“审核登录”事件。在许多情况下,此事件将包含隔离级别。现在,“审核登录”发生在设置实际隔离级别之前,因此报告的隔离级别不会准确反映即将开始的事务的隔离级别。以下是一些关于如何解释它的提示: 当一个连接打开实际上遇到一个新连接时,它总是会报告默认的事务隔离级别,例如你会看到“设置事务隔离级别读取未提交”(正如我所说,这与您的事务的有效隔离级别,因为该级别将在稍后设置)在打开连接然后返回到连接池(即关闭)后,随后的连接打开实际上将重用池中的现有连接。在这种情况下,“审核登录”将报告上次连接返回池时设置的隔离级别。这可以帮助您在事后查看所使用的隔离级别。例如,在您的代码片段中,连接最后一次打开以回滚事务(因为您没有将事务显式标记为已完成)。在该“审核登录”事件中,您应该能够看到以前使用该连接执行查询时有效的隔离级别,由“设置事务隔离级别读取未提交”行表示。将报告上次连接返回池时设置的隔离级别。这可以帮助您在事后查看所使用的隔离级别。例如,在您的代码片段中,连接最后一次打开以回滚事务(因为您没有将事务显式标记为已完成)。在该“审核登录”事件中,您应该能够看到以前使用该连接执行查询时有效的隔离级别,由“设置事务隔离级别读取未提交”行表示。将报告上次连接返回池时设置的隔离级别。这可以帮助您在事后查看所使用的隔离级别。例如,在您的代码片段中,连接最后一次打开以回滚事务(因为您没有将事务显式标记为已完成)。在该“审核登录”事件中,您应该能够看到以前使用该连接执行查询时有效的隔离级别,由“设置事务隔离级别读取未提交”行表示。连接最后一次打开以回滚事务(因为您没有将事务显式标记为已完成)。在该“审核登录”事件中,您应该能够看到以前使用该连接执行查询时有效的隔离级别,由“设置事务隔离级别读取未提交”行表示。连接最后一次打开以回滚事务(因为您没有将事务显式标记为已完成)。在该“审核登录”事件中,您应该能够看到以前使用该连接执行查询时有效的隔离级别,由“设置事务隔离级别读取未提交”行表示。

于 2015-06-17T04:42:43.387 回答