我正在使用嵌套存储过程。 Begin事务和commit / rollback语句在外部SP中。我能否对嵌套SP中发生的所有数据库操作都提交到外部SP中?目前看来,它不能像这样工作。交易上有任何配置允许吗?
ALTER procedure [dbo].[OuterStoredProcedure]
as
begin
declare @nRC int
SET NOCOUNT ON
begin transaction
execute @nRC=InnerStoredProcedure /*includes update statements*/
if (@nRC <> 1)
rollback transaction
else
commit transaction
end
答案 0 :(得分:1)
我已经为您准备了以下考试。如您所见,如果嵌套过程返回0(作为错误),我们可以在第一个过程(父过程)中进行回滚
CREATE TABLE test1010
(
ID Int identity (1,1),
Name nvarchar(20)
)
GO
--DROP PROCEDURE dbo.A1
CREATE PROCEDURE dbo.A1
@name nvarchar(20)
AS
BEGIN
INSERT INTO test1010 VALUES (@name)
return 0
END
GO
--DROP PROCEDURE dbo.AA
CREATE PROCEDURE dbo.AA
@name1 nvarchar(20)
AS
BEGIN
DECLARE @nRC INT;
SET NOCOUNT ON;
BEGIN TRANSACTION;
EXECUTE @nRC = dbo.A1 @name = @name1;
IF(@nRC <> 1)
ROLLBACK TRANSACTION;
ELSE
COMMIT TRANSACTION;
END;
GO
SELECT * FROM test1010
GO
EXECUTE dbo.AA @name1 = 'aa'
GO
SELECT * FROM test1010
还有另一件事。在每个过程中,我们都必须检查交易数量。如果没有交易,则将其打开;如果有交易,则将其保存。最后,我们检查是否打开了事务,如果没有,则提交它,然后让父过程处理事务。
您可以看到我的答案here。
CREATE PROCEDURE Ardi_Sample_Test
@InputCandidateID INT
AS
DECLARE @TranCounter INT;
SET @TranCounter = @@TRANCOUNT;
IF @TranCounter > 0
SAVE TRANSACTION ProcedureSave;
ELSE
BEGIN TRANSACTION;
BEGIN TRY
/*
<Your Code>
*/
IF @TranCounter = 0
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @TranCounter = 0
ROLLBACK TRANSACTION;
ELSE
IF XACT_STATE() <> -1
ROLLBACK TRANSACTION ProcedureSave;
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT @ErrorMessage = ERROR_MESSAGE();
SELECT @ErrorSeverity = ERROR_SEVERITY();
SELECT @ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
GO
在您的过程中始终使用此模式。