Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Community Wiki

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Navigation

Google Ads

Use XACT ABORT to roll back non trappable error transactions

From Wiki

Jump to: navigation, search

Let's say you have a transaction and you want to make sure that it rolls back everything even when you have a non trappable error. What can you do? You can use XACT_ABORT and set it to on. First create this table


  1. CREATE TABLE LogError(ErrorID INT PRIMARY KEY)
  2.     GO


Now run this transaction

  1. BEGIN TRANSACTION TranA
  2.     DECLARE @error INT
  3.      
  4.     INSERT LogError VALUES(1)
  5.     SELECT @error = @@ERROR
  6.     IF @error =0
  7.     BEGIN
  8.        INSERT LogError VALUES(2)
  9.        SELECT @error = @@ERROR
  10.     END
  11.      
  12.      
  13.     IF @error =0
  14.     BEGIN
  15.        INSERT LogError VALUES(3)
  16.        SELECT @error = @@ERROR
  17.     END
  18.      
  19.     --Will blow up here with a non trapable error
  20.     IF @error =0
  21.     BEGIN
  22.        INSERT LogError2 VALUES(1)
  23.        SELECT @error = @@ERROR
  24.     END
  25.      
  26.     IF @error =0
  27.     BEGIN
  28.        COMMIT TRAN TranA
  29.     END
  30.     ELSE
  31.     BEGIN
  32.        ROLLBACK TRAN TranA
  33.     END


So the transaction blew up with the following error Server: Msg 208, Level 16, State 1, Line 22 Invalid object name 'LogError2'.

Now run this query

  1. SELECT * FROM LogError

That is right the first three inserts are in the table

Delete those rows

  1. DELETE LogError


If you set XACT_ABORT on before the transaction then everything will be rolled back Run this block of code

  1. SET XACT_ABORT ON
  2.     BEGIN TRANSACTION TranA
  3.     DECLARE @error INT
  4.      
  5.     INSERT LogError VALUES(1)
  6.     SELECT @error = @@ERROR
  7.     IF @error =0
  8.     BEGIN
  9.        INSERT LogError VALUES(2)
  10.        SELECT @error = @@ERROR
  11.     END
  12.      
  13.      
  14.     IF @error =0
  15.     BEGIN
  16.        INSERT LogError VALUES(3)
  17.        SELECT @error = @@ERROR
  18.     END
  19.      
  20.     --Will blow up here with a non trapable error
  21.     IF @error =0
  22.     BEGIN
  23.        INSERT LogError2 VALUES(1)
  24.        SELECT @error = @@ERROR
  25.     END
  26.      
  27.     IF @error =0
  28.     BEGIN
  29.        COMMIT TRAN TranA
  30.     END
  31.     ELSE
  32.     BEGIN
  33.        ROLLBACK TRAN TranA
  34.     END


Now run this query

  1. SELECT * FROM LogError

That is right no rows. Keep in mind that if you run the first query again in the same query window it will rollback the three rows also since the XACT_ABORT is still set to on, you have to run this

  1. SET XACT_ABORT OFF

To get the same behaviour like when you ran it first you can run the first transaction in another query window.


Applies to:

- SQL Server 2005 - SQL Server 2008


Contributed by: --SQLDenis 02:51, 31 May 2008 (GMT)

Part of SQL Server Programming Hacks

Section Handy tricks

174 Rating: 2.8/5 (25 votes cast)