我正在使用SQL Server Express 2014和Visual Studio 2017。
我有两个存储过程:首先,检查表A中的特定记录是否存在(如果不存在,则创建一个);第二,更新该特定记录的值。
问题是,当使用Jmeter
且有多个用户正在处理此过程时,会出现死锁。如何处理死锁以防止数据库丢失数据,因为死锁XACT_STATE()
等于-1之后,所以我无法将事务从CATCH块回滚到savepoint
,也无法回滚所有事务,因为它将回滚第一个过程的效果。
我还检查了SQL Server Profiler,如果SQL Server尝试回滚到命名的savepoint
,它将冻结事务,并且Visual Studio向我显示错误
System.InvalidOperationException:'此SqlTransaction已完成;它不再可用。
我的代码:
USE TESTDB
GO
ALTER PROCEDURE UPDATEVALUES
@ID int
@PARAMS nvarchar(128)
AS
BEGIN
SET NOCOUNT ON;
SELECT @InnerTranName = '_' + @PARAMS;
SET @Success = 0;
SET @RetryCount = 0;
BEGIN TRANSACTION @InnerTranName;
WHILE @RetryCount < 5 AND @Success = 0
BEGIN
BEGIN TRY
IF @RetryCount = 0
BEGIN
SAVE TRANSACTION @InnerTranName;
END
-- UPDATE PROCEDURE
IF @@TRANCOUNT = 2
SET @Success = 1
END TRY
BEGIN CATCH
DECLARE @error int,
@message varchar(4000),
@xstate int;
SELECT
@error = ERROR_NUMBER(),
@message = ERROR_MESSAGE(),
@xstate = XACT_STATE();
RAISERROR ('CounterValue_Update: %d: %s', 16, 1, @error, @message)
IF @error = 1205
BEGIN
SET @RetryCount = @RetryCount + 1
ROLLBACK TRANSACTION @InnerTranName
END
END CATCH
END
IF @Success = 0
ROLLBACK;
ELSE
COMMIT;
END