更新存储过程中的死锁
Deadlock in Update Stored Procedure
我在数据输入面板上工作,有 300 多个客户端同时在更新数据 table,我正在使用存储过程来执行数据更新 table 看起来像这样..
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.
我创建了一个备份模块来查找错误日志,其中显示此存储过程发生死锁,而更多客户端也尝试更新数据。
我也加了SET TRANSACTION ISOLATION LEVEL READ COMMITTED
但这对我不起作用..
有人可以提供解决方案来解决这种情况吗..
或者如果有某种机制可以保持执行过程直到上一次执行完成
简答
您的 table 上可能缺少索引。首先,您必须检查您的更新是否正在生成 table 扫描,如果是,则在 ID 和 CID 上创建一个索引,看看是否能解决您的问题。
长答案
你的 table 上的更新语句可以引入 table 扫描。这意味着 SQL 服务器读取 table 中的每一行以检查是否需要更新行。在该读取操作期间 SQL 服务器对行发出 (U) 更新锁。如果行需要更新,它将 (U) 锁转换为 (X) 独占锁并持有该锁直到事务结束。 (U) 锁与其他 (U) 或 (X) 锁不兼容。
在您的情况下,您有 2 个会话在等待彼此。每个会话在(不同的)行上放置 X 锁并尝试发出(U)锁并读取其他会话更新的行(持有(X)锁)。实际上有点复杂 - 你涉及超过 2 个会话,但我希望你有一个想法。
创建索引以避免 table 更新期间扫描
我在数据输入面板上工作,有 300 多个客户端同时在更新数据 table,我正在使用存储过程来执行数据更新 table 看起来像这样..
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.
我创建了一个备份模块来查找错误日志,其中显示此存储过程发生死锁,而更多客户端也尝试更新数据。
我也加了SET TRANSACTION ISOLATION LEVEL READ COMMITTED
但这对我不起作用.. 有人可以提供解决方案来解决这种情况吗..
或者如果有某种机制可以保持执行过程直到上一次执行完成
简答
您的 table 上可能缺少索引。首先,您必须检查您的更新是否正在生成 table 扫描,如果是,则在 ID 和 CID 上创建一个索引,看看是否能解决您的问题。
长答案
你的 table 上的更新语句可以引入 table 扫描。这意味着 SQL 服务器读取 table 中的每一行以检查是否需要更新行。在该读取操作期间 SQL 服务器对行发出 (U) 更新锁。如果行需要更新,它将 (U) 锁转换为 (X) 独占锁并持有该锁直到事务结束。 (U) 锁与其他 (U) 或 (X) 锁不兼容。
在您的情况下,您有 2 个会话在等待彼此。每个会话在(不同的)行上放置 X 锁并尝试发出(U)锁并读取其他会话更新的行(持有(X)锁)。实际上有点复杂 - 你涉及超过 2 个会话,但我希望你有一个想法。
创建索引以避免 table 更新期间扫描