Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

IF @@TRANCOUNT > 0     COMMIT TRANSACTION;

Posted on 2015-02-03
6
Medium Priority
?
368 Views
Last Modified: 2015-02-03
Hello Experts;

Need some Expert help with SQL Transactions using TRY, CATCH, COMMIT and ROLLBACK.

Creating a SP that will receive parameters and based on the @DuplicateType will perform 1 of 4 tasks.  If the task is successful COMMIT, else ROLLBACK.

I have attached just the basic SP, but do I have my COMMIT TRANSACTION in the proper place?
COMMIT-TRANS.sql
0
Comment
Question by:wdbates
  • 3
  • 2
6 Comments
 
LVL 70

Accepted Solution

by:
Scott Pletcher earned 2000 total points
ID: 40586959
Yes.

But you really should use XACT_STATE() rather than @@TRANCOUNT.

Also, you need a BEGIN / END block on the IF in the error section:
BEGIN CATCH
       
      IF @@TRANCOUNT > 0
      BEGIN

            SELECT
                  @ErrorMessage   = ERROR_MESSAGE(),
                  @ErrorSeverity  = ERROR_SEVERITY(),
                  @ErrorState     = ERROR_STATE(),
                  @ErrorProcedure = ERROR_PROCEDURE(),
                  @ErrorLine      = ERROR_LINE(),
                  @ErrorNumber    = ERROR_NUMBER();

             ROLLBACK TRANSACTION;
            
             RAISERROR (@ErrorMessage,   -- Message text
                              @ErrorSeverity,  -- Severity
                              @ErrorState,     -- State
                              @ErrorProcedure, -- Procedure
                              @ErrorLine,             -- Line
                              @ErrorNumber     -- Number
                              );
    END
END CATCH;
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 40586963
If you have a "begin tran" and no "commit", the operation will be automatically rolled back so yes you need the commit
0
 

Author Closing Comment

by:wdbates
ID: 40587166
Thank you Scott for the answer and the tip on XACT_STATE.  See the test code below where if the @DuplicateType = 1 you will receive a Divide by Zero error.

Thank you again.

BEGIN

SET XACT_ABORT ON;

BEGIN TRY

BEGIN TRANSACTION

      SET NOCOUNT ON;
      DECLARE @ErrorMessage   NVARCHAR(4000);
    DECLARE @ErrorSeverity  INT;
    DECLARE @ErrorState     INT;
    DECLARE @ErrorProcedure NVARCHAR(128);
    DECLARE @ErrorLine      INT;
    DECLARE @ErrorNumber    INT;
    DECLARE @DuplicateType  INT = 1;
      
      if @DuplicateType = 1 --Duplicate master page to new test page
      begin
            PRINT 'One'
            SELECT 1/0
      end
      
      if @DuplicateType = 2 --Duplicate test page to a new test page.
      begin
            PRINT 'two'
      end
      
      if @DuplicateType = 3 --Duplicate test page to new master page
      begin
            PRINT 'tree'
      end
      
      if @DuplicateType = 4 --Duplicate master page to a new master page.
      begin
            PRINT 'four'
      end
      
      IF (XACT_STATE()) = 1
    BEGIN
        PRINT 'The transaction is committable.' +
              ' Committing transaction.'
        COMMIT TRANSACTION;  
    END;

END TRY

BEGIN CATCH
       
    IF (XACT_STATE()) = -1
    BEGIN
        PRINT 'The transaction is in an uncommittable state.' +
              ' Rolling back transaction.'
            SELECT
                  @ErrorMessage   = ERROR_MESSAGE(),
                  @ErrorSeverity  = ERROR_SEVERITY(),
                  @ErrorState     = ERROR_STATE(),
                  @ErrorProcedure = ERROR_PROCEDURE(),
                  @ErrorLine      = ERROR_LINE(),
                  @ErrorNumber    = ERROR_NUMBER();
                  
        ROLLBACK TRANSACTION;
       
            RAISERROR (@ErrorMessage,   -- Message text
                         @ErrorSeverity,  -- Severity
                         @ErrorState,     -- State
                       @ErrorProcedure, -- Procedure
                       @ErrorLine,             -- Line
                       @ErrorNumber     -- Number
                  );
    END;
   
END CATCH;

END
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 70

Expert Comment

by:Scott Pletcher
ID: 40587187
Looks very good overall.

However, to be thorough, I'd fully check XACT_STATE() in both the TRY area and CATCH areas:

--TRY area
     IF (XACT_STATE()) = 1
     BEGIN
         PRINT 'The transaction is committable.' +
               ' Committing transaction.'
         COMMIT TRANSACTION;  
     END
ELSE IF XACT_STATE() = -1
     BEGIN
         PRINT 'The transaction is committable.' +
               ' Committing transaction.'
         COMMIT TRANSACTION;  
     END;
END TRY
...
BEGIN CATCH
         
     IF (XACT_STATE()) <> 0
     BEGIN
         PRINT 'The transaction had an error.' +
               ' Rolling back transaction.'
    ...
0
 

Author Comment

by:wdbates
ID: 40587214
Is this correct?

BEGIN

SET XACT_ABORT ON;

BEGIN TRY

BEGIN TRANSACTION

      SET NOCOUNT ON;
      DECLARE @ErrorMessage   NVARCHAR(4000);
    DECLARE @ErrorSeverity  INT;
    DECLARE @ErrorState     INT;
    DECLARE @ErrorProcedure NVARCHAR(128);
    DECLARE @ErrorLine      INT;
    DECLARE @ErrorNumber    INT;
    DECLARE @DuplicateType  INT = 1;
      
      if @DuplicateType = 1 --Duplicate master page to new test page
      begin
            PRINT 'One'
            SELECT 1/0
      end
      
      if @DuplicateType = 2 --Duplicate test page to a new test page.
      begin
            PRINT 'two'
      end
      
      if @DuplicateType = 3 --Duplicate test page to new master page
      begin
            PRINT 'tree'
      end
      
      if @DuplicateType = 4 --Duplicate master page to a new master page.
      begin
            PRINT 'four'
      end
      
      IF (XACT_STATE()) = 1
    BEGIN
        PRINT 'The transaction is committable.' +
              ' Committing transaction.'
        COMMIT TRANSACTION;  
    END
    ELSE IF XACT_STATE() = -1
     BEGIN
         PRINT 'The transaction is committable.' +
               ' Committing transaction.'
         COMMIT TRANSACTION;  
     END

END TRY

BEGIN CATCH
       
    IF (XACT_STATE()) <> 0
    BEGIN
        PRINT 'The transaction is in an uncommittable state.' +
              ' Rolling back transaction.'
            SELECT
                  @ErrorMessage   = ERROR_MESSAGE(),
                  @ErrorSeverity  = ERROR_SEVERITY(),
                  @ErrorState     = ERROR_STATE(),
                  @ErrorProcedure = ERROR_PROCEDURE(),
                  @ErrorLine      = ERROR_LINE(),
                  @ErrorNumber    = ERROR_NUMBER();
                  
        ROLLBACK TRANSACTION;
       
            RAISERROR (@ErrorMessage,   -- Message text
                         @ErrorSeverity,  -- Severity
                         @ErrorState,     -- State
                       @ErrorProcedure, -- Procedure
                       @ErrorLine,             -- Line
                       @ErrorNumber     -- Number
                  );
    END;
   
END CATCH;

END
0
 
LVL 70

Expert Comment

by:Scott Pletcher
ID: 40587243
Yep, the TRY part is great.

The CATCH is not quite fully accurate.  Only -1 means "can't be committed".  I also rolled back state 1 because we are in the CATCH block, which means some type of error must have occurred.

BEGIN CATCH
         
     IF (XACT_STATE()) <> 0
     BEGIN
          IF XACT_STATE() = -1
              PRINT 'The transaction is in an uncommittable state.' +
                   ' Rolling back transaction.'
         ELSE --IF XACT_STATE() = 1
              PRINT 'The transaction had an error.' +
                   ' Rolling back transaction.'
             SELECT
                   @ErrorMessage   = ERROR_MESSAGE(),
                   @ErrorSeverity  = ERROR_SEVERITY(),
                   @ErrorState     = ERROR_STATE(),
                   @ErrorProcedure = ERROR_PROCEDURE(),
                   @ErrorLine      = ERROR_LINE(),
                   @ErrorNumber    = ERROR_NUMBER();
                   
         ROLLBACK TRANSACTION;
         
             RAISERROR (@ErrorMessage,   -- Message text
                          @ErrorSeverity,  -- Severity
                          @ErrorState,     -- State
                        @ErrorProcedure, -- Procedure
                        @ErrorLine,             -- Line
                        @ErrorNumber     -- Number
                   );
     END;
     
 END CATCH;

 END
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Ready to get certified? Check out some courses that help you prepare for third-party exams.
This month, Experts Exchange sat down with resident SQL expert, Jim Horn, for an in-depth look into the makings of a successful career in SQL.
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
Via a live example, show how to shrink a transaction log file down to a reasonable size.

886 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question