c# - 单个 SQL Server 表上的死锁

标签 c# sql-server-2008 tsql visual-studio-2008 deadlock

我正在使用 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/

相关文章:

c# - Message Queue 服务不可用

sql - 使用嵌套查询与 CTE 以及性能影响

SQL - 合并两个表,每个表都有一些唯一的列

与 "Ranks"的 SQL 联合

c# - 与供应商无关的检索数据库表模式的方法

c# - 用于空值的适当异常

mysql - 如何在联结表中进行编辑

sql - 在没有一对一关系的情况下从一张表更新另一张表

c# - 通用类型约束只接受数字?

sql-server - 如何拆分平面文件数据并加载到数据库的父子表中?