繁体   English   中英

春季交易-SQL中的ROLLBACK

[英]Spring Transaction - ROLLBACK in SQL

我必须从Java / Spring调用SQL Server存储过程,并且SP中有一个try / catch块,并将错误记录到表中。 因为SP也可以手动调用或从数据库作业中调用,所以那里的日志记录是必需的,但由于Spring的调用是事务性的,因此在我的情况下会导致错误,请参阅https://stackoverflow.com/a/15984867/302151

catch块中的ROLLBACK是否可以解决我的问题?如果是,这是一个好习惯吗? 我的意思是

BEGIN CATCH
  IF XACT_STATE() != 0
    ROLLBACK TRAN
  INSERT INTO TBL_ERROR ...
END CATCH

如果不起作用,建议的解决方案是什么?

您应该在SP中添加对活动事务的支持(从春季呼吁示例)。

BEGIN
  DECLARE @tranCount INT = @@TRANCOUNT
  BEGIN TRY
    IF @tranCount = 0
      BEGIN TRAN
    ELSE 
      SAVE TRAN myTran

    -- Do task here

    IF @tranCount = 0
      COMMIT
  END TRY
  BEGIN CATCH
    DECLARE @xstate INT = XACT_STATE()                              
    IF @xstate = 1
    BEGIN
        IF @trancount = 0       
        BEGIN
            -- The transaction was initiated here and it's valid, so rollback               
            ROLLBACK
        END
        ELSE 
        BEGIN 
            -- The transaction wasn't initialised here.
            -- So just rollback to the save point 
            ROLLBACK TRANSACTION myTran
        END
    END
    ELSE IF @xstate = -1     
    BEGIN
        -- Invalid transaction. There is only one think to do...
        ROLLBACK
    END

    -- Now you can log here (no transaction running so autocommit)

    -- 
    IF @tranCount = 0
    BEGIN
      -- One of both
      ;THROW     -- SQL 2013 and above to rethrow the error (if needed)
      RAISERROR ...  -- SQL 2008R2 and before
    END
    ELSE 
    BEGIN
      -- Here if Spring need a transaction, you can initialise one just beforre rethrow error
      BEGIN TRAN
      -- one of both
      ;THROW     -- SQL 2013 and above to rethrow the error (if needed)
      RAISERROR  -- SQL 2008R2 and before
    END

  END CATCH

您确定没有自动创建的事务就无法从Spring中执行SQL SP吗? 这样会更简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM