【发布时间】: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上是否有索引?如果它需要获得相当多的锁,那么死锁肯定会以类似于此线程stackoverflow.com/questions/2945135/… 的方式发生。正如 KM 建议的那样,设置跟踪以获取死锁图会更有效率。 -
@George2 我的推理方式是,受影响的记录数越多,锁的数量就越多,它们的粒度就越小。