Haftalık olarak "serbest bıraktığım" bir veritabanına sahibim, yani bir yedek personelin başlayabileceğimi gönderiyorum ve son haftadan yükseltmek için kullanabilecekleri bir güncelleme komut dosyası yayınlıyorum (böylece mümkün olduğunca güncel verilerini saklayabilirler)). Bu senaryo elbette çok sayıda DDL - CREATE TABLE
, ALTER TABLE
ve benzerlerini içerir. Bunun temel yapısı şu şekildedir:SQL Server'da CREATE TABLE ifadeleri ROLLBACK'e bağışık mı?
/*
HOW TO USE THIS SCRIPT
1. Run it against your existing DB
2. Check whether there were any errors
3. If there were, issue a rollback by highlighting this:
ROLLBACK
and executing it
4. If there weren't, issue a commit by highlighting this:
COMMIT
and executing it
5. !!! Not doing either of these will leave a transaction open, which will
probably cause all further queries to time out till you do !!!
*/
SET XACT_ABORT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
GO
-- Boilerplate checking and whatnot goes here
GO
-- Guts of operation, part 1
GO
-- Guts of operation, part 2
GO
-- Guts of operation, part 3
GO
-- . . .
GO
-- Guts of operation, part N
GO
-- Boilerplate cleanup stuff here
GO
Ben açık işlem bıraktı ve, elle bitirme ne bağlı başa onlara dikkat edeceğiz. Bunun otomatik olmasını isterdim, ama her şeyin her zaman uzun bir seri halinde birkaç seri olduğunu ve TRY
blokların elbette partileri yaymayacağını düşünürdüm. Böylece acıyı hafifletmek için son zamanlarda SET XACT_ABORT ON;
eklenmiştir. Ne olursa olsun, kendimi onsuz beri denedim ve senaryo için hiçbir fark yaratmıyor. Neyse.
Son zamanlarda, bu komut dosyalarından biri, varolan tablolara denetim kısıtlamaları eklemek için tablolar ve diğer ifadeler oluşturma ifadelerine sahipti. Kullanıcılarımdan biri komut dosyasını çalıştırdı ve kısıtlama üzerinde bir hataya çarptı; Kısıtlamayı ihlal eden önceden varolan verileri vardı. Tamam, sorun değil, bir ROLLBACK
yapın. Doğru, bir tane yapmasına gerek yoktu, XACT_ABORT
zaten yaptı. Git ve veri satırlarını düzelt ... bitti. Şimdi tekrar denemek için! Uhp… ne? Bu sefer kısıtlama yok, ancak tabloların zaten mevcut olduğunu söyleyen CREATE TABLE
ifadelerinde hata çıkıyor! Ha? Geri dönmedi mi?
Bir yedeklemeden geri yükleme ve verileri yeniden düzeltme ve yeniden çalıştırma işlemini bitirdik. Ama bu ne burada ne de orada değil.
Öyleyse, sevgili okuyucular: Bu tabloların oluşturulması işlemin geri dönüşünden nasıl kurtuldu? Onlara yapmamalarını nasıl sağlayabilirim?
DÜZENLEME: Tamam, burada çalıştırabilirsiniz bir örnek.
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);-- Gives error "The ALTER TABLE statement conflicted with the CHECK constraint…", as expected
GO
CREATE TABLE bar (b INT);
GO
ROLLBACK;-- Gives error "The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION." Huh? Where did our transaction go?
GO
SELECT *
FROM bar;-- Gives no error. Table still exists! NOT expected!
GO
USE tempdb;
GO
DROP DATABASE example;
Hayır. Geri bildirime karşı bağışık değiller, açıklamanızdan durumunuzda ne olduğunu bilmek zor. –
Sorunu yeniden oluşturabileceğiniz en basit yolu bulmaya çalışın. Bu, problemi analiz etmemize yardımcı olur. – Andomar