我正在使用SQL Server 2008企业版。我想知道为什么这个存储过程的一个删除语句如果被多个线程同时执行,也会导致死锁?
对于删除语句,Param1是表FooTable的一个列,Param1是另一个表的外键(指另一个表的主键聚类索引列)。对于表FooTable来说,Param1本身没有索引。FooTable有另一列被用作聚类主键,但不是Param1列。
create PROCEDURE [dbo].[FooProc]
@Param1 int
,@Param2 int
,@Param3 int
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
预先感谢。
通常的答案是:看情况而定!:-)
主要是看你的系统有多少流量,以及你使用的交易隔离级别。
隔离级别控制你如何获得数据,以及有多少锁正在进行。 如果你从来没有听说过事务隔离级别,你可能正在使用默认的--READ COMMITTED,这应该不是一个太坏的选择。
然而,如果你出于任何原因使用像
这样的东西,你可能会遇到不是死锁,而是延迟。该表可能会被锁定一段时间,直到你的一个事务完成。如果所有的操作都按这个顺序进行(首先是删除,然后是插入,然后是选择),我看不出你应该遇到任何死锁,真的。
SERIALIZABLE
在这里阅读关于SQL事务隔离级别的内容, www.sql-server-performance.com。