Тупик в обновлении хранимой процедуры
Я работаю над панелью ввода данных, более 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.
Я создаю модуль резервного копирования, чтобы найти журналы ошибок, которые показывают, что эта хранимая процедура заходит в тупик, в то время как другие клиенты также пытаются обновить данные.
я также добавил SET TRANSACTION ISOLATION LEVEL READ COMMITTED
но это не работает для меня.. может кто-нибудь дать решение, чтобы разрешить эту ситуацию..
или если есть какой-то механизм, который удерживает процесс выполнения до завершения предыдущего выполнения
1 ответ
Короткий ответ
Возможно, вам не хватает индекса в вашей таблице. Сначала вам нужно проверить, генерирует ли ваше обновление сканирование таблицы, если это так, создайте один индекс по ID и CID, чтобы увидеть, решит ли это вашу проблему.
Длинный ответ
Оператор обновления на вашей таблице может ввести сканирование таблицы. Это означает, что SQL Server читает каждую строку в вашей таблице, чтобы проверить, нужно ли обновлять строку. Во время этой операции чтения SQL Server выдает (U) блокировку обновления строки. В случае, если необходимо обновить строку, она преобразует (U) блокировку в (X) монопольную блокировку и удерживает эту блокировку до конца транзакции. (U) блокировки несовместимы с другими (U) и (X) замками.
В вашем случае у вас есть 2 сессии, ожидающие друг друга. Каждый сеанс устанавливает блокировку X на (разные) строки и пытается выполнить блокировку (U) и прочитать строку, обновленную другим сеансом (с удерживаемой блокировкой (X)). Это немного сложнее на самом деле - у вас есть более 2 сессий, но я надеюсь, что вы поняли.
Создайте индекс, чтобы избежать сканирования таблицы во время обновления