这样的存储过程会导致死锁吗?
Posted
技术标签:
【中文标题】这样的存储过程会导致死锁吗?【英文标题】:Will such a stored procedure cause deadlock? 【发布时间】:2010-06-04 15:25:39 【问题描述】:我使用的是 SQL Server 2008 Enterprise。我想知道如果同时由多个线程执行,这个存储过程是否会导致死锁?另一个问题是——我们是在存储过程中定义开始和结束事务的最佳实践,还是从客户端代码(例如 ADO.Net 代码)定义开始和结束事务?
create PROCEDURE [dbo].[FooProc]
(
@Param1 int
,@Param2 int
,@Param3 int
)
AS
DELETE FooTable WHERE Param1 = @Param1
INSERT INTO FooTable
(
Param1
,Param2
,Param3
)
VALUES
(
@Param1
,@Param2
,@Param3
)
DECLARE @ID bigint
SET @ID = ISNULL(@@Identity,-1)
IF @ID > 0
BEGIN
SELECT IdentityStr FROM FooTable WHERE ID = @ID
END
提前致谢, 乔治
【问题讨论】:
在 SQL 2008 中 MERGE 能满足您的需求吗?也绝对应该避免@@Identity。使用 SCOPE_IDENTIY 是的,我目前正在分析遗留代码的一些问题,我需要分析死锁是否是由这个存储过程引起的。关于我原来的问题有什么想法或想法吗? @@IDENTITY 提供最新的身份值,如果有触发器,您会从中获取身份,而不是从本地范围内的 INSERT 获取身份。 SCOPE_IDENTITY() 给出本地范围的标识值。使用分析器和死锁图来确定死锁涉及哪些过程。 @George2 -DELETE FooTable WHERE Param1 = @Param1
通常会删除多少条记录? Param1
上是否有索引?如果它需要获得相当多的锁,那么死锁肯定会以类似于此线程***.com/questions/2945135/… 的方式发生。正如 KM 建议的那样,设置跟踪以获取死锁图会更有效率。
@George2 我的推理方式是,受影响的记录数越多,锁的数量就越多,它们的粒度就越小。
【参考方案1】:
回答您问题的唯一可靠方法是run your own stress tests
【讨论】:
对不起,亚历克斯,问题不是很清楚。请在这里讨论,我对此有更清晰的描述。 ***.com/questions/2981121/…【参考方案2】:您提供的代码可能导致死锁。即使存储过程纯粹由以下语句组成,也可能发生死锁。
DELETE FooTable WHERE Param1 = @Param1
取决于可用的确切表定义和索引(您已将其排除在问题之外)。
【讨论】:
为什么包含这个delete语句会导致死锁?还有更多细节吗?我想了解为什么 Param1 上是否有索引会导致死锁? 好吧,我的想法是假设存储过程的调用 1 最终会在页面 x、y、z 上获得页面锁定,但需要页面 a。存储过程的调用 2 最终会在页面 a、b、c 上获得页面锁定,但需要页面 x 然后会发生死锁。 @George2 我们不知道有多少页面会受到影响,因为您没有告诉我们! 我绝对不是死锁大师!查看 Remus Rusanu 的帖子***.com/search?q=user%3A105929+deadlock 单条删除语句还是单条删除记录?如果是后者,那么我也无法构建会发生这种情况的场景。如果是前者,那么我给出的前面的例子就可以做到(可能依赖于并行执行计划只是为了确保锁不是以线性顺序发出的)。以上是关于这样的存储过程会导致死锁吗?的主要内容,如果未能解决你的问题,请参考以下文章