<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      之乎者也,阿彌陀佛

      軟件設(shè)計的原則就是,化繁為簡,化難為易,把人的思維集中在簡單的領(lǐng)域,然后通過有序的組合實現(xiàn)復雜的邏輯。

        博客園  :: 首頁  :: 新隨筆  :: 聯(lián)系 :: 訂閱 訂閱  :: 管理

      我們在寫事務(wù)時經(jīng)常遇到的問題如下:

      消息 266,級別 16,狀態(tài) 2,過程 sp1,第 0 行
      EXECUTE 后的事務(wù)計數(shù)指示 BEGIN 和 COMMIT 語句的數(shù)目不匹配。上一計數(shù) = 1,當前計數(shù) = 0。
      消息 3903,級別 16,狀態(tài) 1,過程 sp2,第 15 行
      ROLLBACK TRANSACTION 請求沒有對應(yīng)的 BEGIN TRANSACTION。
      

       如果這只是一個單獨的事務(wù)引起的,那么很好解決,我們只要檢查下是否遺漏了匹配的BEGIN tran 和 COMMIT tran即可,但是如果2個存儲過程都是用事務(wù)寫的,那么就即使每個存儲過程的事務(wù)寫法都正常,也會報這個錯誤,

      這是因為只要子事務(wù)里有回滾語句:如ROLLBACK      那么全局的@@TRANCOUNT被直接置為0了,導致父事務(wù)提交時發(fā)現(xiàn) @@TRANCOUNT=0  報錯 ,sql server會認為當前不存在任何事務(wù),在父存儲過程中任何的COMMIT TRAN或

      ROLLBACK 語句都會找不到它對應(yīng)的 BEGIN TRAN   

      下面我們用一個實例來看下:

      假設(shè)有一張表,ID為非自增主鍵

      USE [TestDB]
      GO
      
      /****** Object:  Table [dbo].[test]    Script Date: 02/17/2013 15:44:35 ******/
      SET ANSI_NULLS ON
      GO
      
      SET QUOTED_IDENTIFIER ON
      GO
      
      SET ANSI_PADDING ON
      GO
      
      CREATE TABLE [dbo].[test](
          [ID] [bigint] NOT NULL,
          [UserID] [bigint] NULL,
          [Name] [varchar](50) NULL,
       CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED 
      (
          [ID] ASC
      )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
      ) ON [PRIMARY]
      
      GO
      
      SET ANSI_PADDING OFF
      GO

       

       我們常規(guī)的寫一個插入的子存儲過程如下:

      USE [TestDB]
      GO
      /****** Object:  StoredProcedure [dbo].[innertranv1]    Script Date: 02/17/2013 15:46:46 ******/
      SET ANSI_NULLS ON
      GO
      SET QUOTED_IDENTIFIER ON
      GO
      
      --內(nèi)層事務(wù)存儲過程,演示如何處理才能在嵌套的事務(wù)存儲過程中正確處理事務(wù)
      ALTER PROCEDURE [dbo].[innertranv1]
          @ID BIGINT ,
          @UserID BIGINT ,
          @Name VARCHAR(50)
      AS 
          BEGIN
              SET XACT_ABORT ON    
              BEGIN TRAN    
           
              IF(EXISTS(SELECT TOP 1 * FROM dbo.test WHERE ID=@ID))    
              BEGIN
                      ROLLBACK        
                      RETURN 0 ;  
              END
              
              --業(yè)務(wù)邏輯開始
              
              INSERT  dbo.test
                      ( ID, UserID, Name)
              VALUES  ( @ID, 
                        @UserID,
                        @Name  
                        )
              --業(yè)務(wù)邏輯結(jié)束
              
              IF @@error <> 0 
                  BEGIN  
                      ROLLBACK                                   
                      RETURN 0;  
                  END        
        
              COMMIT   
           SET XACT_ABORT OFF;   
           RETURN 1 ; 

      END

      調(diào)用的父存儲過程如下:

      USE [TestDB]
      GO
      /****** Object:  StoredProcedure [dbo].[outertranv2]    Script Date: 02/17/2013 16:09:09 ******/
      SET ANSI_NULLS ON
      GO
      SET QUOTED_IDENTIFIER ON
      GO
      
      -- =============================================
      -- Author:        <Author,,Name>
      -- Create date: <Create Date,,>
      -- Description:    <外層存儲過程>
      -- =============================================
      ALTER PROCEDURE [dbo].[outertranv2]
          @ID BIGINT ,
          @UserID BIGINT ,
          @Name VARCHAR(50)
      AS 
              
          BEGIN TRAN     
          DECLARE @result INT
          EXEC @result = innertranv1 @ID =@ID, @UserID =@UserID, @Name = @Name
          IF ( @result <= 0 ) 
              BEGIN
                  ROLLBACK TRAN  ;                 
                  RETURN ;
              END 
          COMMIT TRAN        

      我們執(zhí)行父存儲過程:

      USE [TestDB]
      GO
      
      DECLARE    @return_value int
      
      EXEC    @return_value = [dbo].[outertranv2]
              @ID = 0,
              @UserID = 0,
              @Name = N'0'
      
      SELECT    'Return Value' = @return_value
      
      GO

      第一次提交正常,再次執(zhí)行就會出現(xiàn)如下錯誤:

      消息 266,級別 16,狀態(tài) 2,過程 innertranv1,第 0EXECUTE 后的事務(wù)計數(shù)指示 BEGINCOMMIT 語句的數(shù)目不匹配。上一計數(shù) = 1,當前計數(shù) = 0。
      消息 3903,級別 16,狀態(tài) 1,過程 outertranv2,第 18ROLLBACK TRANSACTION 請求沒有對應(yīng)的 BEGIN TRANSACTION

       

      如何解決?我們修改子存儲過程如下:

      USE [TestDB]
      GO
      /****** Object:  StoredProcedure [dbo].[innertran]    Script Date: 02/17/2013 16:26:26 ******/
      SET ANSI_NULLS ON
      GO
      SET QUOTED_IDENTIFIER ON
      GO
      --內(nèi)層事務(wù)存儲過程,演示如何處理才能在嵌套的事務(wù)存儲過程中正確處理事務(wù)
      ALTER PROCEDURE [dbo].[innertran]
          @ID BIGINT ,
          @UserID BIGINT ,
          @Name VARCHAR(50)
      AS 
          BEGIN
              DECLARE @TRANCOUNT int=(select @@TRANCOUNT)
          
              SET XACT_ABORT ON
              SET @TRANCOUNT=(select @@TRANCOUNT)
              PRINT '未進入子事務(wù)前全局@@TRANCOUNT'+CAST(@TRANCOUNT AS VARCHAR(50))    
              BEGIN TRAN tran1      --開始事務(wù) 
              SAVE TRAN tranpoint   --保存事務(wù)點
              SET @TRANCOUNT=(select @@TRANCOUNT)
              PRINT '進入子事務(wù)后全局@@TRANCOUNT'+CAST(@TRANCOUNT AS VARCHAR(50))    
             
              IF(EXISTS(SELECT TOP 1 * FROM dbo.test WHERE ID=@ID))    
              BEGIN
                      ROLLBACK TRAN tranpoint ;   --回滾保存點的事務(wù)   
                      COMMIT TRAN tran1 ;            --提示當前事務(wù)
                      SET @TRANCOUNT=(select @@TRANCOUNT)  
                      PRINT '回滾子事務(wù)后全局@@TRANCOUNT'+CAST(@TRANCOUNT AS VARCHAR(50))     
                                
                      RETURN 0 ;  
              END
              
              --業(yè)務(wù)邏輯開始
              
              INSERT  dbo.test
                      ( ID, UserID, Name)
              VALUES  ( @ID, 
                        @UserID,
                        @Name  
                        )
              --業(yè)務(wù)邏輯結(jié)束
              
              IF @@error <> 0 
                  BEGIN  
                      ROLLBACK TRAN tranpoint ; --回滾保存點的事務(wù)   
                      COMMIT TRAN tran1 ;          --提示當前事務(wù)  
                      SET @TRANCOUNT=(select @@TRANCOUNT)  
                      PRINT '回滾子事務(wù)后全局@@TRANCOUNTT'+CAST(@TRANCOUNT AS VARCHAR(50))     
                                               
                      RETURN 0;  
                  END        
        
              COMMIT TRAN tran1 ;    
              SET XACT_ABORT OFF;    
              SET @TRANCOUNT=(select @@TRANCOUNT)  
              PRINT '提交子事務(wù)后全局@@TRANCOUNT'+CAST(@TRANCOUNT AS VARCHAR(50))
                 
              RETURN 1 ;
      
          END

       

      父過程如下:  

      USE [TestDB]
      GO
      /****** Object:  StoredProcedure [dbo].[outertran]    Script Date: 02/17/2013 16:27:13 ******/
      SET ANSI_NULLS ON
      GO
      SET QUOTED_IDENTIFIER ON
      GO
      -- =============================================
      -- Author:        <Author,,Name>
      -- Create date: <Create Date,,>
      -- Description:    <外層存儲過程>
      -- =============================================
      ALTER PROCEDURE [dbo].[outertran]
          @ID BIGINT,
          @UserID BIGINT,
          @Name VARCHAR(50)
      AS 
          DECLARE @TRANCOUNT int=(select @@TRANCOUNT)
          PRINT '未進入父事務(wù)前全局@@TRANCOUNT:'+CAST(@TRANCOUNT AS VARCHAR(50))
          
              
          BEGIN TRAN 
          SET @TRANCOUNT=(select @@TRANCOUNT) 
          PRINT '進入父事務(wù)后全局@@TRANCOUNT:'+CAST(@TRANCOUNT AS VARCHAR(50))    
              
          DECLARE @result INT
      
          EXEC @result = innertran @ID = @ID, @UserID = @UserID, @Name =@Name
      
          IF ( @result <= 0 ) 
              BEGIN
                  ROLLBACK TRAN  ;
                  SET @TRANCOUNT=(select @@TRANCOUNT) 
                  PRINT '回滾父事務(wù)后全局@@TRANCOUNT:'+CAST(@TRANCOUNT AS VARCHAR(50)) 
                              
                  RETURN ;
              END 
          COMMIT TRAN 
          SET @TRANCOUNT=(select @@TRANCOUNT) 
          PRINT '提交父事務(wù)后全局@@TRANCOUNT:'+CAST(@TRANCOUNT AS VARCHAR(50))

       

       調(diào)用父存儲過程:

      USE [TestDB]
      GO
      
      DECLARE    @return_value int
      
      EXEC    @return_value = [dbo].[outertran]
              @ID = 0,
              @UserID = 0,
              @Name = N'0'
      
      SELECT    'Return Value' = @return_value
      
      GO

      結(jié)果如下:

      未進入父事務(wù)前全局@@TRANCOUNT:0
      進入父事務(wù)后全局@@TRANCOUNT:1
      未進入子事務(wù)前全局@@TRANCOUNT:1
      進入子事務(wù)后全局@@TRANCOUNT:2
      回滾子事務(wù)后全局@@TRANCOUNT:1
      回滾父事務(wù)后全局@@TRANCOUNT:0

      不會再報"EXECUTE 后的事務(wù)計數(shù)指示 BEGINCOMMIT 語句的數(shù)目不匹配"之類的錯誤了,實際上就是在每個嵌套的子過程中標明當前事務(wù)點,每個子事務(wù) 只提交/回滾 子事務(wù)點,而不是回滾整個事務(wù)!

       

       

      posted on 2013-02-17 16:31  搏擊的小船  閱讀(12329)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 人妻中文字幕精品一页| 影音先锋亚洲成aⅴ人在| 中国亚洲女人69内射少妇| 色综合久久久久综合体桃花网| 国产精品久久久久婷婷五月 | 国内不卡不区二区三区| 黄瓜视频在线观看| 伦伦影院午夜理论片| 亚洲欧美日韩成人综合一区| 性欧美vr高清极品| 久青草国产综合视频在线| 国产裸体美女视频全黄| 精品91在线| 国产高颜值不卡一区二区| 精品国精品无码自拍自在线| 欧美大胆老熟妇乱子伦视频| 精品国产人妻一区二区三区久久| 久久人人爽人人爽人人av| 久久精品国产亚洲av熟女| 中文人妻无码一区二区三区在线| 亚洲国产成人久久综合一区77| 亚洲精品成人久久久| 中文字幕有码日韩精品| 免费无码高潮流白浆视频| 新绛县| 国产真人无遮挡免费视频| 上司人妻互换中文字幕| 亚洲一区二区三区18禁| 亚洲精品久荜中文字幕| 真实国产老熟女无套内射| 久久天天躁夜夜躁狠狠| 日韩免费美熟女中文av| 手机看片日本在线观看视频| 亚洲精品二区在线播放| 国内精品大秀视频日韩精品 | 精品无码国产污污污免费| 亚洲熟女综合色一区二区三区| 国产极品粉嫩尤物一区二区| 在线观看成人永久免费网站| av色国产色拍| 国产精品九九久久精品女同|