|
With my database upgrade scripts, I typically just have one long script that makes the necessary changes for that database version. However, if one statement fails halfway through the script, it leaves the database in an inconsistent state. How can I make the entire upgrade script one atomic operation? I've tried just wrapping all of the statements in a transaction, but that does not work. Even with SET XACT_ABORT ON, if one statement fails and rolls back the transactions, the rest of the statements just keep going. I would like a solution that doesn't require me to write IF @@TRANCOUNT > 0... before each and every statement. For example:
(comments are locked)
|
|
Here is what I do: Before start of any DDL changes:
Before any single DDL statement:
After any single DDL statement:
At the end of all DDL statements: I've been playing around with this. It seems that if your DDL statement references a table that does not exist, then the error is not caught in the CATCH block.
Oct 28 '09 at 01:16 PM
NYSystemsAnalyst
No, if you look at this http://technet.microsoft.com/en-us/library/ms179296.aspx about a quarter of the way down it states that object name resolution errors aren't caught. That's why immediately afterwards there is the IF @@TRANCOUNT = 0 check...
Oct 28 '09 at 01:22 PM
Matt Whitfield ♦♦
Then this solution will work most of the time. If one of the DDL statements causes one of these un-caught errors (meaning no entry into the errors table), then the DDL statements that followed that error will always be committed because you begin a new transaction after each Try...Catch block.
Oct 28 '09 at 02:01 PM
NYSystemsAnalyst
Very good point. In that case, I believe the IF @@TRANCOUNT = 0 bit should then insert a row into the schema modification errors table saying 'hang on, i expected trancount to be 1'... What do you think?
Oct 29 '09 at 08:11 AM
Matt Whitfield ♦♦
I have modified the 'after any single' bit to incorporate that now.
Oct 29 '09 at 08:14 AM
Matt Whitfield ♦♦
(comments are locked)
|
|
Do you have Enterprise Edition? A database snapshot would make this extremely clean. The other thing you can do, and what I've done, is keep a rollback script handy for each change. If it fails, run the rollback to that point. I've viewed a deployment as a go-no go chance. If one thing fails, everything rolls back, not just that one part. If we decide to do a partial deployment, I'd rebuild the roll forward/roll back scripts. No, we don't have Enterprise Edition.
Oct 28 '09 at 12:31 PM
NYSystemsAnalyst
(comments are locked)
|

