tags:

views:

1932

answers:

4

hi all.

What is the benefit of using "SET XACT_ABORT ON" in a stored procedure?

A: 

It is used in transaction management to ensure that any errors result in the transaction being rolled back.

Dan Diplo
+6  A: 

SET XACT_ABORT ON instructs SQL Server to rollback the entire transaction and abort the batch when a run-time error occurs. It covers you in cases like a command timeout occurring on the client application rather than within SQL Server itself (which isn't covered by the default XACT_ABORT OFF setting.)

Since a query timeout will leave the transaction open, SET XACT_ABORT ON is recommended in all stored procedures with explicit transactions (unless you have a specific reason to do otherwise) as the consequences of an application performing work on a connection with an open transaction are disastrous.

There's a really great overview on Dan Guzman's Blog,

Ben Griswold
+1 for client command timeouts
gbn
many thanks to you Ben
odiseh
You're welcome.
Ben Griswold
+2  A: 

In my opinion SET XACT_ABORT ON was made obsolete by the addition of BEGIN TRY/BEGIN CATCH in SQL 2k5. Before exception blocks in Transact-SQL it was really difficult to handle errors and unbalanced procedures were all too common (procedures that had a different @@TRANCOUNT at exit compared to entry).

With the addition of Transact-SQL exception handling is much easier to write correct procedures that are guaranteed to properly balance the transactions. For instance I use this template for exception handling an nested transactions that allows me to write atomic procedures that rollback only their own work in case of recoverable errors.

One of the main issues Transact-SQL procedures face is data purity: sometimes the parameters received or the data in the tables are just plain wrong, resulting in duplicate key errors, referential constrain errors, check constrain errors and so on and so forth. After all, that's exactly the role of these constrains, if these data purity errors would be impossible and all caught by the business logic, the constrains would be all obsolete (dramatic exaggeration added for effect). If XACT_ABORT is ON then all these errors result in the entire transaction being lost, as opposed to being able to code exception blocks that handle the exception gracefully. A typical example is trying to do an INSERT and reverting to an UPDATE on PK violation.

Remus Rusanu
Except for client timeouts... and my view is the SET XACT_ABORT is more effective in SQL 2005 because behaviour is more predictable: far fewer batch aborting errors.
gbn
client *timeouts* are application bugs. No app should impose a command timeout, ever. Is such an appallingly poor practice that the default SqlClient timeout gives me a headache every time I think how could they ship something like that.You can guide your entire Transact-SQL error handling around the timeout problem, or you can code the client properly and address the business problems in error handling. Of course, my view is from a developer point of view. the ones in the admin/dba role usually view the world differently, given they are stuck with the apps other create.
Remus Rusanu
I agree somewhat, but I plan my error handling around all eventualities, because I know I'll the get the blame as Developer DBA if a command timeout occurs.
gbn
+3  A: 

Quoting MSDN:

When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back. When SET XACT_ABORT is OFF, in some cases only the Transact-SQL statement that raised the error is rolled back and the transaction continues processing.

In practice this means that some of the statements might fail, leaving the transaction 'partially completed', and there might be no sign of this failure for a caller.

A simple example:

INSERT INTO t1 VALUES (1/0)    
INSERT INTO t2 VALUES (1/1)    
SELECT 'Everything is fine'

This code would execute 'successfully' with XACT_ABORT OFF, and will terminate with an error with XACT_ABORT ON ('INSERT INTO t2' will not be executed, and a client application will raise an exception).

As a more flexible approach, you could check @@ERROR after each statement (old school), or use TRY...CATCH blocks (MSSQL2005+). Personally I prefer to set XACT_ABORT ON whenever there is no reason for some advanced error handling.

VladV