我正在使用 SQL Server 2008 Enterprise。并使用 ADO.Net + C# + .Net 3.5 + ASP.Net 作为客户端访问数据库。当我访问 SQL Server 2008 表时,我总是从我的 C# + ADO.Net 代码调用存储过程。
我对表 FooTable 进行了 3 次操作。而Multiple connections会依次同时执行,即执行delete,执行insert,然后执行select。 每个语句(删除/插入/选择)都是单个存储过程中的一个单独的单独事务。
我的问题是delete语句会不会死锁? 我的猜测是,如果多个连接对同一个Param1值进行操作,是否有可能发生死锁?
BTW:对于下面的语句,Param1是表FooTable的列,Param1是另一个表的外键(指另一个表的另一个主键聚簇索引列)。表 FooTable 的 Param1 本身没有索引。 FooTable 有另一列用作聚簇主键,但不是 Param1 列。
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
这是事件监控表的样子,
ProcessID System Process Login Database Status Opened transaction Command Application Wait Time Wait Type CPU
52 No Foo suspended 0 DELETE .Net SqlClient Data Provider 4882 LCK_M_U 0
53 No George Foo suspended 2 DELETE .Net SqlClient Data Provider 12332 LCK_M_U 0
54 No George Foo suspended 2 DELETE .Net SqlClient Data Provider 6505 LCK_M_U 0
(a lot of rows like the row for process ID 54)
最佳答案
我会在 FooTable 中添加一个关于 Param1 的索引;没有它,DELETE 将进行全表扫描,这会产生死锁问题。
编辑
根据您的事件详细信息,您似乎没有死锁,您有阻塞,许多删除正在排队,而只有一个删除发生。同样,在 Param1 上建立索引可以缓解这种情况,如果没有它,每次删除都将进行全表扫描以查找要删除的记录,而在发生这种情况时,其他删除必须等待。如果您在 Param1 上有索引,它的处理速度会快得多,您不会看到现在的阻塞。
如果出现死锁,系统将终止涉及的进程之一,否则将不会有任何进程;使用阻塞,事情会处理,但如果表很大的话会非常慢。
关于c# - 单个 SQL Server 表上的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3075885/