亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

包含嘗試捕獲回滾模式的嵌套存儲過程?

包含嘗試捕獲回滾模式的嵌套存儲過程?

慕絲7291255 2019-07-05 12:58:20
包含嘗試捕獲回滾模式的嵌套存儲過程?我對以下模式的副作用和潛在問題感興趣:CREATE PROCEDURE [Name]ASBEGIN     BEGIN TRANSACTION     BEGIN TRY        [...Perform work, call nested procedures...]     END TRY    BEGIN CATCH        ROLLBACK TRANSACTION         RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]     END CATCHEND據我所知,該模式在與單個過程一起使用時是合理的-該過程要么完成其所有語句而沒有錯誤,要么回滾所有操作并報告錯誤。但是,當一個存儲過程調用另一個存儲過程來執行某個子單元的工作時(但有一項了解,即有時會單獨調用較小的過程),我看到一個與回滾有關的問題-發出一條信息性消息(級別16),聲明The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION...我認為這是因為子過程中的回滾總是回滾最外層的事務,而不僅僅是在子過程中開始的事務。如果發生任何錯誤(并且向客戶端報告為SQL錯誤),我確實希望整個事件回滾并中止,我只是不確定來自試圖回滾一個已經回滾的事務的外部層產生的所有副作用。也許是一張支票@@TRANCOUNT在每個嘗試捕捉層做回滾之前?最后是客戶端(Linq2SQL),它有自己的事務層:try{     var context = new MyDataContext();     using (var transaction = new TransactionScope())     {                    // Some Linq stuff         context.SubmitChanges();         context.MyStoredProcedure();         transactionComplete();     }}catch{     // An error occured!}如果存儲過程“MySubProcedure”調用內MyStoredProcedure會引發一個錯誤,我是否可以確保以前在MyStoredProcedure中完成的所有操作都將被回滾,SubmitChanges所做的所有Linq操作都將被回滾,并最終記錄該錯誤?或者我需要改變我的模式,以確保整個操作是原子的,同時仍然允許單獨使用子部分(即子過程應該仍然具有相同的原子保護)。
查看完整描述

3 回答

?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

這是我們的模板(刪除錯誤日志)

這是設計用來處理

解釋:

  • 所有TXN開始和提交/回滾必須配對,以便@@TRANCOUNT在出入境時是相同的。

  • 不匹配@@TRANCOUNT導致錯誤266,因為

    • BEGIN TRAN增量@@TRANCOUNT

    • COMMIT減量@@TRANCOUNT

    • ROLLBACK回報@@TRANCOUNT降至零

  • 你不能減少@@TRANCOUNT適用于當前范圍
    這就是你認為的“內部交易”

  • SET XACT_ABORT ON取消由不匹配引起的錯誤266。@@TRANCOUNT
    也處理像這樣的問題“SQLServer事務超時”日照

  • 這允許客戶端txns(如LINQ),單個存儲過程可能是分布式或XA事務的一部分,或者僅僅是在客戶端代碼(比如.NET TransactionScope)中啟動的一個存儲過程。

用法:

  • 每個存儲的proc必須符合相同的模板。

摘要

  • 所以不要創建比你需要的更多的txn

密碼

CREATE PROCEDURE [Name]ASSET XACT_ABORT, NOCOUNT ONDECLARE @starttrancount intBEGIN TRY    SELECT @starttrancount = @@TRANCOUNT    
IF @starttrancount = 0
        BEGIN TRANSACTION

       [...Perform work, call nested procedures...]

    IF @starttrancount = 0 
        COMMIT TRANSACTIONEND TRYBEGIN CATCH    IF XACT_STATE() <> 0 AND @starttrancount = 0 
        ROLLBACK TRANSACTION;
    THROW;
    --before SQL Server 2012 use 
    --RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]END CATCH
GO

注:

  • 回滾檢查實際上是多余的,因為SET XACT_ABORT ON..然而,它讓我感覺更好,看上去很奇怪沒有,并考慮到一些情況下,你不想要它。

  • 魯薩努有一個相似殼它使用保存點。我更喜歡原子DB調用,不像他們的文章那樣使用部分更新


查看完整回答
反對 回復 2019-07-05
?
慕神8447489

TA貢獻1780條經驗 獲得超1個贊

為了解決返回@AlexKuznetsov所提到的錯誤號和行號的問題,可以這樣引發錯誤:


DECLARE @ErrorMessage NVARCHAR(4000)

DECLARE @ErrorSeverity INT

DECLARE @ErrorState INT

DECLARE @ErrorLine INT

DECLARE @ErrorNumber INT


SELECT @ErrorMessage = ERROR_MESSAGE(),

@ErrorSeverity = ERROR_SEVERITY(),

@ErrorState = ERROR_STATE(),

@ErrorNumber = ERROR_NUMBER(),

@ErrorLine = ERROR_LINE()


RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorNumber, @ErrorLine)


查看完整回答
反對 回復 2019-07-05
  • 3 回答
  • 0 關注
  • 493 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號