<p>I just got surprised by something in TSQL.  I thought that if xact_abort was on, calling something like</p>

<pre><code>raiserror('Something bad happened', 16, 1);
</code></pre>

<p>would stop execution of the stored procedure (or any batch).</p>

<p>But my ADO.NET error message just proved the opposite.  I got both the raiserror error message in the exception message, plus the next thing that broke after that.</p>

<p>This is my workaround (which is my habit anyway), but it doesn't seem like it should be necessary:</p>

<pre><code>if @somethingBadHappened
    begin;
        raiserror('Something bad happened', 16, 1);
        return;
    end;
</code></pre>

<p>The docs say this:</p>

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

<p>Does that mean I must be using an explicit transaction?</p>

This is By Design
TM
, as you can see on
Connect
by the SQL Server team's response to a similar question:
Thank you for your feedback. By design, the XACT_ABORT set option does not impact the behavior of the RAISERROR statement. We will consider your feedback to modify this behavior for a future release of SQL Server.
Yes, this is a bit of an issue for some who hoped
```
RAISERROR
```
with a high severity (like
```
16
```
) would be the same as an SQL execution error - it's not.
Your workaround is just about what you need to do, and using an explicit transaction doesn't have any effect on the behavior you want to change.