sqlserver 存儲過程 try catch TRANSACTION (轉)

原文:http://www.cnblogs.com/yun_shuai/archive/2010/09/20/1831546.htmlhtml

 

/*

1. 輕微錯誤(嚴重性級別爲0-10):默認狀況下不會給客戶程序發送錯誤消息,繼續工做。也就是說它沒法被CATCH到

2. 中等錯誤(嚴重性級別爲11-19):可以被CATCH到(無論是在T-SQL裏面仍是在客戶程序裏面)

3. 嚴重錯誤(嚴重性級別爲20-25):SQL Server將強制把鏈接關掉。很顯然這也不可能被CATCH到


【重點提示!!】

因爲業務的複雜或者系統性能問題,導致數據庫sql語句執行較久。

致使客戶端網頁已經鏈接超時(如設置爲30秒)

此時數據庫批處理語句未執行完成,客戶session斷開,至關於中斷操做,相似【案例1】的中斷。

事務是沒有提交或回滾的,資源仍在佔用,致使發生堵塞或死鎖!~



【解決方法】:

在批處理語句前加上 SET XACT_ABORT ON
當客戶端中斷的時候,未執行完成則回滾操做,及時釋放資源。 sql


--查看 XACT_ABORT 是否打開
SELECT (CASE WHEN (16384 & @@OPTIONS) = 16384 THEN 'ON' ELSE 'OFF' END) AS XACT_ABORT; 數據庫


*/ session

 

 

 

CREATE PROCEDURE YourProcedure    
AS
BEGIN
    SET NOCOUNT ON;ide

    BEGIN TRY---------------------開始捕捉異常
       BEIN TRAN------------------開始事務
        UPDATE A SET A.names = B.names FROM 表1 AS A INNER JOIN 表2 AS B ON A.id = B.id函數

        UPDATE A SET A.names = B.names FROM 表1 AS A INNER JOIN 表2 AS B ON A.TEST = B.TEST性能

    COMMIT TRAN -------提交事務
    END TRY-----------結束捕捉異常
    BEGIN CATCH------------有異常被捕獲
        IF @@TRANCOUNT > 0---------------判斷有沒有事務
        BEGIN
            ROLLBACK TRAN----------回滾事務
        END 
        EXEC YourLogErrorProcedure-----------執行存儲過程將錯誤信息記錄在表當中
    END CATCH--------結束異常處理
ENDspa

 

---------------------------------------------記錄操做錯信息的存儲過程--------------------------------------------.net

CREATE PROCEDURE YourLogErrorProcedure
    @ErrorLogID [int] = 0 OUTPUT -- contains the ErrorLogID of the row inserted
AS                               -- by uspLogError in the ErrorLog table
BEGIN
    SET NOCOUNT ON;orm

    -- Output parameter value of 0 indicates that error 
    -- information was not logged
    SET @ErrorLogID = 0;

    BEGIN TRY
        -- Return if there is no error information to log
        IF ERROR_NUMBER() IS NULL
            RETURN;

        -- Return if inside an uncommittable transaction.
        -- Data insertion/modification is not allowed when 
        -- a transaction is in an uncommittable state.
        IF XACT_STATE() = -1
        BEGIN
            PRINT 'Cannot log error since the current transaction is in an uncommittable state. ' 
                + 'Rollback the transaction before executing uspLogError in order to successfully log error information.';
            RETURN;
        END

        INSERT [dbo].[OperateErrorLog] 
            (
            [OperateName], 
            [ErrorNumber], 
            [ErrorSeverity], 
            [ErrorState], 
            [ErrorProcedure], 
            [ErrorLine], 
            [ErrorMessage]
            ) 
        VALUES 
            (
            CONVERT(sysname, CURRENT_USER), 
            ERROR_NUMBER(),
            ERROR_SEVERITY(),
            ERROR_STATE(),
            ERROR_PROCEDURE(),
            ERROR_LINE(),
            ERROR_MESSAGE()
            );
        SET @ErrorLogID = @@IDENTITY;
    END TRY
    BEGIN CATCH
        PRINT 'An error occurred in stored procedure uspLogError: ';
        EXECUTE YourPrintErrorProcedure;-----------------打印錯誤信息的存儲過程
        RETURN -1;
    END CATCH
END;

 

CREATE PROCEDURE YourPrintErrorProcedure
AS
BEGIN
    SET NOCOUNT ON;

    -- Print error information. 
    PRINT 'Error ' + CONVERT(varchar(50), ERROR_NUMBER()) +
          ', Severity ' + CONVERT(varchar(5), ERROR_SEVERITY()) +
          ', State ' + CONVERT(varchar(5), ERROR_STATE()) + 
          ', Procedure ' + ISNULL(ERROR_PROCEDURE(), '-') + 
          ', Line ' + CONVERT(varchar(5), ERROR_LINE());
    PRINT ERROR_MESSAGE();
END;

CREATE TABLE [dbo].[ErrorLog](
    [ErrorLogID] [int] IDENTITY(1,1) NOT NULL,
    [ErrorTime] [datetime] NOT NULL CONSTRAINT [DF_ErrorLog_ErrorTime]  DEFAULT (getdate()),
    [UserName] [sysname] COLLATE Chinese_PRC_CI_AS NOT NULL,
    [ErrorNumber] [int] NOT NULL,
    [ErrorSeverity] [int] NULL,
    [ErrorState] [int] NULL,
    [ErrorProcedure] [nvarchar](126) COLLATE Chinese_PRC_CI_AS NULL,
    [ErrorLine] [int] NULL,
    [ErrorMessage] [nvarchar](4000) COLLATE Chinese_PRC_CI_AS NOT NULL,
 CONSTRAINT [PK_ErrorLog_ErrorLogID] PRIMARY KEY CLUSTERED 
(
    [ErrorLogID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/WeiZhang_son_Ding/archive/2010/02/05/5291732.aspx

 

 

http://www.cnblogs.com/BpLoveGcy/archive/2010/03/22/1691407.html

ALTER PROC usp_AccountTransaction  

  1.     @AccountNum INT,  
  2.     @Amount DECIMAL  
  3. AS  
  4. BEGIN  
  5. BEGIN TRY --Start the Try Block..  
  6. BEGIN TRANSACTION -- Start the transaction..  
  7. UPDATE MyChecking SET Amount = Amount - @Amount  
  8. WHERE AccountNum = @AccountNum  
  9. UPDATE MySavings SET Amount = Amount + @Amount  
  10. WHERE AccountNum = @AccountNum  
  11. COMMIT TRAN -- Transaction Success!  
  12. END TRY  
  13. BEGIN CATCH  
  14.         IF @@TRANCOUNT > 0  
  15. ROLLBACK TRAN --RollBack in case of Error  
  16. -- you can Raise ERROR with RAISEERROR() Statement including the details of the exception  
  17.         --RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1)       

            DECLARE @ErrorMessage NVARCHAR(4000);
       DECLARE @ErrorSeverity INT;
     DECLARE @ErrorState INT;

     SELECT 
      @ErrorMessage = ERROR_MESSAGE(),
      @ErrorSeverity = ERROR_SEVERITY(),
      @ErrorState = ERROR_STATE();

   -- Use RAISERROR inside the CATCH block to return error
   -- information about the original error that caused
   -- execution to jump to the CATCH block.
     RAISERROR (@ErrorMessage, -- Message text.
          @ErrorSeverity, -- Severity.
          @ErrorState -- State.
          );

  1.   
  2.     END CATCH  
  3.   
  4. END  
  5.   
  6. GO  

 

  1. BEGIN TRY  
  2.   
  3.     SELECT GETDATE()  
  4.   
  5.     SELECT 1/0--Evergreen divide by zero example!  
  6.   
  7. END TRY  
  8.   
  9. BEGIN CATCH  
  10.   
  11.     SELECT 'There was an error! ' + ERROR_MESSAGE()  
  12.   
  13.     RETURN  
  14.   
  15. END CATCH;  

 

2.得到錯誤信息的函數表: 

 

下面系統函數在CATCH塊有效.能夠用來獲得更多的錯誤信息:

函數 描述
ERROR_NUMBER() 返回致使運行 CATCH 塊的錯誤消息的錯誤號。
ERROR_SEVERITY() 返回致使 CATCH 塊運行的錯誤消息的嚴重級別
ERROR_STATE() 返回致使 CATCH 塊運行的錯誤消息的狀態號
ERROR_PROCEDURE() 返回出現錯誤的存儲過程名稱
ERROR_LINE() 返回發生錯誤的行號
ERROR_MESSAGE() 返回致使 CATCH 塊運行的錯誤消息的完整文本

 

    •   BEGIN TRY  
    •   
    •     Try Statement 1  
    •   
    •     Try Statement 2  
    •   
    •     ...  
    •   
    •     Try Statement M  
    •   
    • END TRY  
    •   
    • BEGIN CATCH  
    •   
    •     Catch Statement 1  
    •   
    •     Catch Statement 2  
    •   
    •     ...  
    •   
    •     Catch Statement N  
    •   
    • END CATCH  
相關文章
相關標籤/搜索