8

Based on the Books Online documentation of SET XACT_ABORT ON, i get the impression that if a T-SQL statement raises a run-time error, the entire transaction is terminated and rolled back:

Remarks

When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.

Testing this in SQL Server 2008 R2:

SET XACT_ABORT ON;
BEGIN TRANSACTION;
PRINT 'TranCount befor an error = '+CAST(@@Trancount AS varchar(50))

DROP TABLE QuertyAsdf

PRINT 'TranCount after an error = '+CAST(@@Trancount AS varchar(50))

Gives the output:

TranCount befor an error = 1
Msg 3701, Level 11, State 5, Line 6
Cannot drop the table 'QwertyAsdf', because it does not exist or you do not have permission.
TranCount after an error = 1

i was also under the impression that SET XACT_ABORT ON terminates the batch if there's an error:

SET XACT_ABORT ON instructs SQL Server to rollback the entire transaction and abort the batch when a run-time error occurs.

That sounds handy. How can i make it do that too?

Community
  • 1
  • 1
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • 3
    ["when XACT_ABORT is ON, not all errors terminate the batch ... Compilation errors (which normally terminate the scope) do not terminate the batch."](http://www.sommarskog.se/error-handling-I.html#XACT_ABORT) – Martin Smith Jul 24 '12 at 06:33
  • @MartinSmith Presumably this is not a compilation error, as it passes compilation and begins executing the batch – Ian Boyd Jul 25 '12 at 19:55
  • Generally speaking statements that reference non existent objects are subject to deferred compile. Not sure if this is the case for DDL statements. – Martin Smith Jul 25 '12 at 20:34
  • http://stackoverflow.com/questions/917773/do-i-really-need-to-use-set-xact-abort-on/919279#919279 –  Jul 30 '12 at 18:12

2 Answers2

5

The SQL Server only rollback transactions when Severity level greater or equals 16.

See example:

Msg 544, Level 16, State 1, Line 1
Cannot insert explicit value for identity column in table 'ORC_ORCAMENTO' whenIDENTITY_INSERT is set to OFF.

Test on SQL Server 2008 R2

SET XACT_ABORT ON;
BEGIN TRANSACTION;
PRINT 'TranCount befor an error = '+CAST(@@Trancount AS varchar(50))
insert into ORC_ORCAMENTO (ORCID, ORCNOME, ORCATIVO) VALUES (1, 'TESTE_ALEXP', 0);
PRINT 'TranCount after an error = '+CAST(@@Trancount AS varchar(50))

Returns

TranCount befor an error = 1
Msg 544, Level 16, State 1, Line 5
Cannot insert explicit value for identity column in table 'ORC_ORCAMENTO' when IDENTITY_INSERT is set to OFF.
TranCount after an error = 0

See Microsoft Error Message Levels on

https://learn.microsoft.com/en-us/sql/relational-databases/errors-events/database-engine-events-and-errors

Branko Dimitrijevic
  • 50,809
  • 10
  • 93
  • 167
Roger Medeiros
  • 783
  • 7
  • 9
1

When you use xact abort on, in the try catch statement, you can manually raise an error to make the transaction roll back.

set xact_abort on;

begin try
    ...dml statements here....

if conditions here...
    raiseerror(....);

end try
begin catch

end catch
Artur Udod
  • 4,465
  • 1
  • 29
  • 58
AgentSQL
  • 71
  • 1
  • 2