Ian*_*oyd 10 sql-server stored-procedures sql-server-2008-r2
查看SQL Server联机丛书,Microsoft似乎有一种(不正确的)方法来处理存储过程中的嵌套事务:
嵌套交易
显式事务可以嵌套.这主要用于支持存储过程中的事务,这些事务可以从事务中已有的进程调用,也可以从没有活动事务的进程调用.
该示例继续显示一个启动其自己的事务的存储过程("该过程强制执行其事务,而不管执行它的任何进程的事务模式."):
CREATE PROCEDURE TransProc @PriKey INT, @CharCol CHAR(3) AS
   BEGIN TRANSACTION InProc
      ...
   COMMIT TRANSACTION InProc;
Run Code Online (Sandbox Code Playgroud)
然后可以在没有运行事务的情况下调用此过程:
EXECUTE TransProc 3,'bbb';
Run Code Online (Sandbox Code Playgroud)
或者使用显式交易:
BEGIN TRANSACTION OutOfProc;
EXEC TransProc 1, 'aaa';
COMMIT TRANSACTION OutOfProc
Run Code Online (Sandbox Code Playgroud)
他们没有解决的是存储的产品时会发生什么:
没有:
SET XACT_ABORT ON在规范示例中的任何地方.
如果我不知道更好,我会想到这条线:
以下示例显示嵌套事务的预期用途.
应该真的读
以下示例显示了如何不使用嵌套事务.
除非有人能说出这个BOL例子的正面或反面?
小智 32
您需要在事务中使用try catch块.因此,如果您在catch块中收到错误,那么您可以回滚您的事务.
请参阅下面的sql server代码.
BEGIN TRANSACTION;
BEGIN TRY
    -- Some code
    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION;
END CATCH;
Run Code Online (Sandbox Code Playgroud)
        小智 13
CREATE PROCEDURE [usp_my_procedure_name]
AS
BEGIN
  SET NOCOUNT ON;
  DECLARE @trancount int;
  SET @trancount = @@trancount;
  BEGIN TRY
    IF @trancount = 0
      BEGIN TRANSACTION
      ELSE
        SAVE TRANSACTION usp_my_procedure_name;
    -- Do the actual work here
    lbexit:
      IF @trancount = 0
      COMMIT;
  END TRY
  BEGIN CATCH
    DECLARE @error int,
            @message varchar(4000),
            @xstate int;
    SELECT
      @error = ERROR_NUMBER(),
      @message = ERROR_MESSAGE(),
      @xstate = XACT_STATE();
    IF @xstate = -1
      ROLLBACK;
    IF @xstate = 1 AND @trancount = 0
      ROLLBACK
    IF @xstate = 1 AND @trancount > 0
      ROLLBACK TRANSACTION usp_my_procedure_name;
    RAISERROR ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message);
  END CATCH
END
Run Code Online (Sandbox Code Playgroud)