I have a database that I “release” weekly, which means that I am sending a backup copy that people can start with, and I am posting an update script that they can use to update from last week (so that they can save their current data as possible). This script, of course, contains a lot of DDL - CREATE TABLE , ALTER TABLE and so on. Its main structure is as follows:
SET XACT_ABORT ON; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION; GO
You will notice that I left the transaction open and told them to complete it manually, depending on what happened. I would prefer it to be automatic, but despair of him, given that all this is always a long series of several parties, and TRY blocks cannot cover parties, of course. Thus, the recent addition of SET XACT_ABORT ON; relieves pain. Regardless, I tried it myself, since without it, and it does not matter for the script. Anyway.
Recently, one of these scenarios had instructions for creating tables and other statements to add control constraints to existing tables. One of my users ran a script and hit a restriction error; it turns out that he had pre-existing data that violates the restriction. Well, no problem, do a ROLLBACK . That's right, there was no need to do this, XACT_ABORT already did it. Delete and correct the data lines ... done. Now try again! Uhp ... what? This time there is no restriction error, but there are errors in the CREATE TABLE statements saying that the tables already exist ...! A? Didn't he roll back?
We have finished restoring from the backup and reinstalling the data and re-executing. But it is neither here nor there.
So, dear readers: How were these tables created to roll back a transaction? How can I make them not do this?
EDIT: Alright, here is an example you can run.
USE tempdb; GO CREATE DATABASE example; GO USE example; GO CREATE TABLE foo (a INT); GO INSERT INTO foo VALUES (100); GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION; GO ALTER TABLE foo ADD CHECK (a < 10);