[英]deadlock on a single SQL Server table
我正在使用SQL Server 2008 Enterprise。 并使用ADO.Net + C#+。Net 3.5 + ASP.Net作为客户端访问数据库。 当我访问SQL Server 2008表时,我总是从我的C#+ ADO.Net代码调用存储过程。
我在表FooTable上有3个操作。 并且多个连接将在序列中同时执行它们,即执行delete,execute insert然后执行select。 每个语句(删除/插入/选择)都是单存储过程中的单独的单个事务。
我的问题是,删除语句是否可能发生死锁? 我的猜测是,如果多个连接在同一个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)
我会在Param1上添加一个索引到FooTable; 没有它,DELETE正在进行全表扫描,这会产生死锁问题。
编辑
根据您的活动详细信息,它看起来不像您有死锁,您有阻塞,许多删除正在排队,同时发生一次删除。 同样,对Param1进行索引可以缓解这种情况,如果没有它,每次删除都会进行全表扫描以查找要删除的记录,而当发生这种情况时,其他删除必须等待。 如果你在Param1上有一个索引,那么它的处理速度会快得多,你就不会看到你现在的阻塞。
如果你有死锁,系统将杀死一个涉及的进程,否则什么都不会处理; 如果表格很大,那么事情就会处理,但事情会很慢。
我不认为你会陷入僵局(这不是我的专业领域),但明确的交易可能是更好的选择。 此代码会想到一个场景如下
对该过程的两个并发调用以Param1值5执行,同时删除然后同时插入,因此现在您有两个Param1值为5的记录。根据您的数据一致性要求,这可能会或可能不会引起您的关注。
您可以选择实际执行更新,如果没有行受影响(请检查@@ rowcount),然后在事务中执行Insert all。 或者更好的是,请查看Merge以在单个语句中执行插入/更新操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.