【发布时间】:2015-10-05 10:40:34
【问题描述】:
我目前正在寻找我们遇到的死锁和 SQL Server 问题。发生了相当多的死锁。以下死锁图是我关注的(来自现场环境):
<deadlock>
<victim-list>
<victimProcess id="process41fce08"/>
<victimProcess id="process40c9048"/>
</victim-list>
<process-list>
<process id="process41fce08" taskpriority="0" logused="0" waitresource="KEY: 5:72057595257749504 (03e6337489b1)" waittime="2133" ownerId="213210603" transactionname="SELECT" lasttranstarted="2015-09-30T09:06:29.133" XDES="0xe1d9dcb0" lockMode="RangeS-S" schedulerid="4" kpid="3608" status="suspended" spid="113" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2015-09-30T09:06:29.133" lastbatchcompleted="2015-09-30T09:06:29.133" clientapp=".Net SqlClient Data Provider" hostname="MYSERVER" hostpid="1692" loginname="MYUSER" isolationlevel="serializable (4)" xactid="213210603" currentdb="5" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="" line="25" stmtstart="1876" stmtend="5346" sqlhandle="0x030005007f7dca111202de0024a400000100000000000000"/>
</executionStack>
<inputbuf> Proc [Database Id = 5 Object Id = 298483071] THIS IS READ STORED PROCEDURE </inputbuf>
</process>
<process id="process40c9048" taskpriority="0" logused="0" waitresource="KEY: 5:72057595257749504 (03e6337489b1)" waittime="2137" ownerId="213210579" transactionname="SELECT" lasttranstarted="2015-09-30T09:06:29.130" XDES="0x8051fcb0" lockMode="RangeS-S" schedulerid="2" kpid="3908" status="suspended" spid="101" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2015-09-30T09:06:29.130" lastbatchcompleted="2015-09-30T09:06:29.130" clientapp=".Net SqlClient Data Provider" hostname="MYSERVER" hostpid="5328" loginname="MYUSER" isolationlevel="serializable (4)" xactid="213210579" currentdb="5" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="" line="25" stmtstart="1876" stmtend="5346" sqlhandle="0x030005007f7dca111202de0024a400000100000000000000"/>
</executionStack>
<inputbuf> Proc [Database Id = 5 Object Id = 298483071] THIS IS READ STORED PROCEDURE </inputbuf>
</process>
<process id="process11eca3708" taskpriority="0" logused="247980" waitresource="OBJECT: 5:1745427475:0 " waittime="1913" ownerId="213208999" transactionname="user_transaction" lasttranstarted="2015-09-30T09:06:28.640" XDES="0xc2f3ae90" lockMode="IX" schedulerid="3" kpid="272" status="suspended" spid="72" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2015-09-30T09:06:29.410" lastbatchcompleted="2015-09-30T09:06:29.410" clientapp=".Net SqlClient Data Provider" hostname="MYSERVER" hostpid="4172" loginname="MYUSER" isolationlevel="serializable (4)" xactid="213208999" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="" line="6" stmtstart="232" sqlhandle="0x0300050098df89558d028500b59f00000100000000000000"/>
</executionStack>
<inputbuf> Proc [Database Id = 5 Object Id = 1435099032] THIS IS READ UPDATE PROCEDURE </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057595257749504" dbid="5" objectname="" indexname="" id="lockee29f480" mode="X" associatedObjectId="72057595257749504">
<owner-list/>
<waiter-list>
<waiter id="process41fce08" mode="RangeS-S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057595257749504" dbid="5" objectname="" indexname="" id="lockee29f480" mode="X" associatedObjectId="72057595257749504">
<owner-list>
<owner id="process11eca3708" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process40c9048" mode="RangeS-S" requestType="wait"/>
</waiter-list>
</keylock>
<objectlock lockPartition="0" objid="1745427475" subresource="FULL" dbid="5" objectname="" id="lock128d27d80" mode="S" associatedObjectId="1745427475">
<owner-list>
<owner id="process41fce08" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="process11eca3708" mode="IX" requestType="convert"/>
</waiter-list>
</objectlock>
</resource-list>
</deadlock>
查看死锁受害者进程 id = process41fce08,这是一个选择存储过程,似乎在 Serializable 事务下运行。
但是,查看堆栈跟踪,未使用事务范围。没有创建显式事务。一个简单的 SqlConnection 和 SqlCommand 用于执行存储过程。
查看调用堆栈以在我的本地开发机器上执行相同的代码路径,这显示了在 ReadCommitted 下运行的事务隔离级别。使用以下方法检索此信息:
select
CASE transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN 'ReadUncommitted'
WHEN 2 THEN 'ReadCommitted'
WHEN 3 THEN 'Repeatable'
WHEN 4 THEN 'Serializable'
WHEN 5 THEN 'Snapshot'
ELSE 'Unknown'
END
FROM sys.dm_exec_sessions
where session_id = @@SPID
从存储过程内部。如果我打电话:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
在存储过程中,我在上面的选择中看到了隔离级别的变化。这是我所期望的,也是我在开发环境中看到的:
Default Isolation Level in ADO.NET
所以考虑到:
- TransactionScope 未在调用堆栈中设置
- 存储过程内部没有设置隔离级别
似乎有什么东西正在设置实时环境的隔离级别?问题是什么设置或强制它可序列化?
代码在 .NET 4 上的 MVC3 应用程序中运行。
【问题讨论】:
标签: sql sql-server ado.net transactionscope distributed-transactions