所有关于SQL Server死锁的文档都讨论了操作1锁定资源A然后尝试访问资源B并且操作2锁定资源B并尝试访问资源A的情况.
但是,我常常在一些繁忙的应用程序中看到select和更新之间甚至多个选择之间的死锁.我发现死锁跟踪输出的一些细节非常难以理解但我真的只想了解什么可能导致两个单独操作之间的死锁.当然,如果一个选择具有读锁定,则更新应该在获得独占锁之前等待,反之亦然?
这种情况发生在SQL Server 2005上,而不是我认为这会产生影响.
我在SQL Server 2008上的SELECT/UPDATE上遇到了死锁问题.我从这个帖子中读到了答案:SQL Server在select/update或多个选择之间出现死锁,但我仍然不明白为什么会出现死锁.
我在以下测试用例中重新创建了这种情况.
我有一张桌子:
CREATE TABLE [dbo].[SessionTest](
[SessionId] UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL,
[ExpirationTime] DATETIME NOT NULL,
CONSTRAINT [PK_SessionTest] PRIMARY KEY CLUSTERED (
[SessionId] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[SessionTest]
ADD CONSTRAINT [DF_SessionTest_SessionId]
DEFAULT (NEWID()) FOR [SessionId]
GO
Run Code Online (Sandbox Code Playgroud)
我首先尝试从此表中选择一条记录,如果记录存在,则将到期时间设置为当前时间加上一些间隔.它使用以下代码完成:
protected Guid? GetSessionById(Guid sessionId, SqlConnection connection, SqlTransaction transaction)
{
Logger.LogInfo("Getting session by id");
using (SqlCommand …Run Code Online (Sandbox Code Playgroud) 有问题的Sql Server 2008 R2实例是一个重负载OLTP生产服务器.几天前出现了死锁问题,但仍未解决.我们收到了Xml死锁报告,其中列出了死锁中涉及的存储过程以及其他一些细节.我将首先尝试从这个xml中列出事实:
死锁涉及两个存储过程,例如SP1和SP2.据报道SP1在隔离级别运行的"序列化"和SP2是在"READCOMMITTED"运行.
我们调查了以下内容:
我们在SP或代码中将IsolationLevel SP1设置为"Serializable"吗? - 没有.
是否其他SP的IsolationLevel是"Serializable"调用SP1? - 没有.
SP1使用的表是否被隔离级别为"可序列化"的任何其他SP调用? - 是的 有些SP将隔离级别设置为"可序列化"并访问与SP1相同的表,但我们不知道它们是否在死锁时运行,因为死锁
报告仅显示SP1和SP2.
思路:
我们考虑了以下可能的原因:
发生死锁是因为SP1正在运行为"可序列化". - 当我没有设置时,为什么这个SP在Serializable中运行?隔离级别是否升级(如锁定)?如果我们弄明白并将其作为ReadCommitted运行,问题是否会得到解决?
任何其他SP正在运行,锁定SP1使用的表并导致SP1和SP2之间的死锁. - 这个SP不会列在死锁报告中吗?死锁报告能否错过这种依赖?如果是,那么我们可能只获得部分信息.但是,这仍然无法解决SP1在Serializable中的运行方式.
建议:
如果此信息不足以解决问题,我如何从SQL Server获取更多信息以用于我的目的以及我应该尝试收集哪些信息?
您在解决此问题时会采取的其他思路吗?
更新:
这是死锁的跟踪日志信息.我已经更改了SP等的名称,但已经检查并验证了更改不会遗漏任何相关信息.检查代码后面的注释以获取有关表等的更多信息.
?<EVENT_INSTANCE>
<EventType>DEADLOCK_GRAPH</EventType>
<PostTime>2010-09-07T11:27:47.870</PostTime>
<SPID>16</SPID>
<TextData>
<deadlock-list>
<deadlock victim="process5827708">
<process-list>
<process id="process5827708" taskpriority="0" logused="0" waitresource="KEY: 7:72057594228441088 (8d008a861f4f)"
waittime="5190" ownerId="1661518243" transactionname="SELECT" lasttranstarted="2010-09-07T11:27:42.657"
XDES="0x80bf3b50" lockMode="RangeS-S" schedulerid="4" kpid="2228" status="suspended" spid="76" sbid="0"
ecid="0" priority="0" trancount="0" lastbatchstarted="2010-09-07T11:27:42.657"
lastbatchcompleted="2010-09-07T11:27:42.657" clientapp=".Net SqlClient Data Provider"
hostname="xxx" hostpid="5988" loginname="xxx" isolationlevel="serializable (4)"
xactid="1661518243" …Run Code Online (Sandbox Code Playgroud) database sql-server deadlock sql-server-2008 sql-server-2008-r2