更新存储过程中的死锁

时间:2015-11-03 08:50:21

标签: c# sql sql-server stored-procedures database-deadlocks

我正在开发一个数据输入面板,有300多个客户端同时在数据表上更新数据,我使用存储过程在数据表中执行更新,如下所示..

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:                <Author,,Name>
-- Create date: <Create Date,,>
-- Description:        <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[Update_Tbl_Client_Bpo_Data]

@Id int,
@CId varchar(50),
@Tbc_No varchar(200),
@Name varchar(200),
@EmailId varchar(200),
@MobileNo varchar(50),
@Gender varchar(50),
@LicenseNo varchar(200),
@GirNo varchar(200),
@PanNo varchar(200),
@H_Address varchar(500),
@H_City varchar(200),
@H_PinNo varchar(200),
@H_county varchar(200),
@H_State varchar(200),
@O_Address varchar(200),
@O_City varchar(200),
@O_PinNo varchar(200),
@LAL varchar(200),
@MRNNo varchar(200),
@AF varchar(200),
@NRI varchar(200),
@CP varchar(200),
@Status varchar(200)

AS
BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;



        update Tbl_Client_Bpo_Data 
set

Tbc_No=@Tbc_No,
Name=@Name,
EmailId=@EmailId,
MobileNo=@MobileNo,
Gender=@Gender,
LicenseNo=@LicenseNo,
GirNo=@GirNo,
PanNo=@PanNo,
H_Address=@H_Address,
H_City=@H_City,
H_PinNo=@H_PinNo,
H_county=@H_county,
H_State=@H_State,
O_Address=@O_Address,
O_City=@O_City,
O_PinNo=@O_PinNo,
LAL=@LAL,
MRNNo=@MRNNo,
AF=@AF,
NRI=@NRI,
CP=@CP,
Status=@Status from  Tbl_Client_Bpo_Data  where Id=@Id and CId=@CId 
END

这个存储过程会像这样得到死锁错误......

transaction was deadlocked on lock resources with another process and has been chosen as the deadlock victim. rerun the transaction.

我创建一个备份模块来查找错误日志,该错误日志显示此存储过程变为死锁,而更多客户端也尝试更新数据。 Error Logs

我还添加了SET TRANSACTION ISOLATION LEVEL READ COMMITTED

但它对我不起作用.. 有人可以提供解决方案来解决这种情况。

或者是否有某种机制在前一次执行完成之前保存执行过程

1 个答案:

答案 0 :(得分:4)

简短回答

您可能在表上缺少索引。首先,您必须检查您的更新是否正在生成表扫描,如果是,请在ID和CID上创建一个索引以查看是否可以解决您的问题。

答案很长

表上的更新语句可以引入表扫描。这意味着,SQL Server会读取表中的每一行以检查是否需要更新行。在该读取操作期间,SQL Server在行上发出(U)更新锁定。如果需要更新行,它会将(U)锁定转换为(X)独占锁定并保持该锁定直到事务结束。 (U)锁与其他(U)或(X)锁不兼容。

在您的情况下,您有2个会话等待对方。每个会话将X锁定在(不同的)行上并尝试发出(U)锁定并读取由其他会话更新的行(保持(X)锁定)。实际上它有点复杂 - 你有超过2个会话,但我希望你有个主意。

创建索引以避免在更新期间进行表扫描