Следующее sproc реализовано в соответствии с шаблоном в этой статье: Обработка исключений и вложенные транзакции . Предполагается, что этот sproc обрабатывает взаимоблокировки и вызывается другим sproc, который уже создает транзакцию. Некоторое волшебство с BEGIN / COMMIT внутренней транзакции не совпадает, потому что я получаю это исключение: Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0
. Насколько я понимаю, catch выполняется, @xstate = -1
true и вся внешняя транзакция откатывается.
Есть идеи, где происходит несоответствие?
CREATE PROCEDURE [dbo].[mysproc]
AS
BEGIN
SET NOCOUNT ON;
SET DEADLOCK_PRIORITY LOW;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRY
DECLARE @trancount int;
SET @trancount = @@TRANCOUNT;
IF (@trancount = 0)
BEGIN TRANSACTION;
ELSE
SAVE TRANSACTION InnerTran;
--
-- do some work that can potentially cause a deadlock
--
END TRY
BEGIN CATCH
DECLARE @xstate int
SELECT @xstate = XACT_STATE()
IF (@xstate = - 1)
ROLLBACK;
IF (@xstate = 1 and @trancount = 0)
ROLLBACK;
IF (@xstate = 1 and @trancount > 0)
ROLLBACK TRANSACTION InnerTran;
END CATCH
END
GO