2016-08-02 113 views
0

我已经使用了保存事务和回滚,但仍然发生相同的异常。回滚事务请求没有相应的开始事务

它给了我这个错误:

Msg 3903, Level 16, State 1, Procedure HALAQATI_ttttttttttttt, Line 144 The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.

更新

Msg 50000, Level 16, State 1, Procedure HALAQATI_ttttttttttttt, Line 160 usp_my_procedure_name: 102: Incorrect syntax near '='.

存储过程是:

ALTER Proc [dbo].[HALAQATI_ttttttttttttt] 
       @tf_commentparam nvarchar(100), 
       @tf_secsuggdate int, 
       @tf_testplace nvarchar(50), 
       @tf_time nvarchar(7), 
       @tf_day int, 
       @an_id int, 
       @ResponseText nvarchar(max) out, 
       @ResponseNum int out -- (0 = everything is ok , 1 = error or wrong data) 

AS 
    DECLARE @startingTranCount int 
    SET @startingTranCount = @@TRANCOUNT 
Begin 
SET XACT_ABORT ON 
SET NoCount ON 
    BEGIN TRY 
    IF @startingTranCount > 0 
     SAVE TRANSACTION mySavePointName 
    ELSE 
     BEGIN TRANSACTION 

      DECLARE @return_value_FIRST int, 
       @tf_id int, 
       @createddate int, 
       @UnitIDFromStudentID int, 
       @StudentIDFromAutoNominationID int 

      set @createddate = (select dbo.f_getHijNowByInteger()); 

      set @StudentIDFromAutoNominationID = (select st_id from tbl_autonomination where an_id = @an_id); 

      set @UnitIDFromStudentID = (select sec_id from tbl_secmsq where sm_id = 
             (select sm_id from tbl_ring where rg_id = 
             (select Ring_ID from HALAQATI_VIEW_GetAllStudents where Student_ID = @StudentIDFromAutoNominationID))) 
             --/////////////////////////////////-- 
      DECLARE @return_value_SECOND int,@msg nvarchar(500) 

      Declare @BranchNumFromAnID int = (select ne_branchno from tbl_nomineeexam where an_id = @an_id) 
             --/////////////////////////////////-- 
      DECLARE @return_value_THIRD int 
             --/////////////////////////////////-- 

    EXEC  @return_value_FIRST = [dbo].[sp_inserttestform] 
       @tf_comment = @tf_commentparam, 
       @tf_date = @createddate, 
       @tf_secsuggdate = @tf_secsuggdate, 
       @tf_testplace = @tf_testplace, 
       @tf_unittype = 1, -- قطاع 
       @tf_unitid = @UnitIDFromStudentID, 
       @tf_id = @tf_id OUTPUT, 
       @tf_userid = 10,--رقم جلال سعيد في التعليمية, 
       @tf_type = 1, --آلي 
       @tf_time = @tf_time, 
       @tf_day = @tf_day, 
       @tf_TFtype = 1 -- أجزاء 

       if (@return_value_FIRST != 0 and @tf_id is null) 
       begin 

        if (@return_value_FIRST = 1)   
         begin 
          set @ResponseText = 'أقل من يوم وأكثر من 15 يوم' 
          set @ResponseNum = 1 
          return 
         end 
        else if (@return_value_FIRST = 2) 
         begin 
          set @ResponseText = 'لايوجد نقاط كافية للترشيح' 
          set @ResponseNum = 1 
          return 
         end 
        else if (@return_value_FIRST = 3) 
         begin 
          set @ResponseText = 'لم يتم ربط مركز الإشراف أو المجمع بمشرف لجان' 
          set @ResponseNum = 1 
          return 
         end 
        else 
         begin 
          set @ResponseText = 'هناك خطأ حاول في وقت لاحق' 
          set @ResponseNum = 1 
          return 
         end 
           IF @startingTranCount > 0 
          ROLLBACK TRANSACTION MySavePointName 
         ELSE 
          ROLLBACK 
       End 

    EXEC  @return_value_SECOND = [dbo].[sp_insertAutoNominee] 
       @tf_id = @tf_id, 
       @st_id = @StudentIDFromAutoNominationID, 
       @an_id = @an_id, 
       @ne_branchno = @BranchNumFromAnID, 
       @ne_userid = 10, 
       @msg = @msg OUTPUT 

       if (@return_value_SECOND != 0 or @return_value_SECOND is not null) 
        begin 
         --ROLLBACK TRANSACTION 

         if CHARINDEX('بنفس الفرع ونتيجته ناجح',@msg) > 0 
          begin 
           set @ResponseText = 'لا يمكن إضافة ترشيح للطالب لأن له ترشيح سابق بنفس الفرع ونتيجته ناجح أو لم يختبر بعد' 
           set @ResponseNum = 1 
           return 
          end    
         if CHARINDEX('خلال السبعة أيام',@msg) > 0 
          begin 
           set @ResponseText = 'لا يمكن إضافة ترشيح للطالب لأنه غاب عن اختبار في نفس الفرع خلال السبعة أيام الماضية' 
           set @ResponseNum = 1 
           return 
          end      
         if CHARINDEX('خلال الأربعة عشر يوماً',@msg) > 0 
          begin 
           set @ResponseText = 'لا يمكن إضافة ترشيح للطالب لأنه رسب في نفس الاختبار خلال الأربعة عشر يوماً الماضية' 
           set @ResponseNum = 1 
           return 
          end    
           IF @startingTranCount > 0 
          ROLLBACK TRANSACTION MySavePointName 
         ELSE 
          ROLLBACK      
        end 

    EXEC  @return_value_THIRD = [dbo].[sp_changeTFState] 
       @tf_state = 4, 
       @tf_id = @tf_id, 
       @tf_chatsys = NULL, 
       @tf_testdate = @tf_secsuggdate, 
       @tf_time = @tf_time, 
       @tf_day = @tf_day, 
       @ne_cerprintdate = NULL 

       IF @startingTranCount = 0 

        set @ResponseText = 'تم إعتماد و ترشيح الطالب إلى الإختبار بنجاح , وتم إرسال كافة البيانات إلى قسم الإختبارات في الجمعية' 
        set @ResponseNum = 0 
        COMMIT 
    END TRY 
    --BEGIN CATCH 
    --IF @startingTranCount > 0 
    -- ROLLBACK TRANSACTION MySavePointName 
    --ELSE 
    -- ROLLBACK TRANSACTION 
    -- set @ResponseText = ERROR_MESSAGE() 
    -- set @ResponseNum = 1 
    --END CATCH 
     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 @startingTranCount = 0 
      rollback 
     if @xstate = 1 and @startingTranCount > 0 
      rollback transaction usp_my_procedure_name; 

     raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ; 
    end catch 
End 
+0

你已经有了一个BEGIN TRANSACTION那么ROLLBACK TRANSACTION,再进行第二次ROLLBACK TRANSACTION没有BEGIN - 我看有 – Cato

+0

@AndrewDeighton好的开始,但是当我需要在sp块的两个位置使用多于回滚的时候怎么办? – Loai

+0

第一次ROLLBACK之后,你真的想继续第二次操作吗?如果你不这样做,那么你需要设置一个标志来避免第二次操作。 – Cato

回答

1

不能在CATCH块回滚W/O首先咨询的状态XACT_STATE()。你的catch块可能在之后执行事务已经回滚(例如,想象一下发生死锁)。

的正确模式见Exception handling and nested transactions

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 
+0

谢谢Xact_state信息..一个问题,虽然..会达到catch语句之前死锁回滚本身? – TheGameiswar

+1

遇到死锁时,受害者事务将被中止并回退,并且只有在回滚完成后*才是受害者会话中引发的死锁异常。 –

+0

@RemusRusanu谢谢,我不问为什么这个问题依然存在,我已经改变了我的WholeCatch与你的,但另一个问题发生,我已经更新线程错误 – Loai