Solved

IF @@TRANCOUNT > 0     COMMIT TRANSACTION;

Posted on 2015-02-03
6
218 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 69

Accepted Solution

by:
Scott Pletcher earned 500 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
Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

 
LVL 69

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 69

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

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

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

Suggested Solutions

Nowadays, some of developer are too much worried about data. Who is using data, who is updating it etc. etc. Because, data is more costlier in term of money and information. So security of data is focusing concern in days. Lets' understand the Au…
This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
This video shows, step by step, how to configure Oracle Heterogeneous Services via the Generic Gateway Agent in order to make a connection from an Oracle session and access a remote SQL Server database table.
Viewers will learn how to use the INSERT statement to insert data into their tables. It will also introduce the NULL statement, to show them what happens when no value is giving for any given column.

813 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now