Wie verwende ich Transaktionen mit SQL Server DDL?

20

Ich habe eine Login-Tabelle, in die alle Einfügungen von einer einzelnen gespeicherten Prozedur durchgeführt werden.

CREATE TABLE dbo.LogTable(
    LogRefnr int IDENTITY(1, 1) NOT NULL,
    LogQuery varchar(255) NOT NULL,
    LogTime datetime NOT NULL,
    logQueryDuration int NULL,
    LogSessionID int NULL,
 CONSTRAINT PK_Log PRIMARY KEY CLUSTERED  (LogRefnr)
)
go


Create procedure DBO.LogInsert ( @Query varchar(255), @time datetime, @duration int, @SessinID int) as
begin
    Insert into LogTable ( LogRefnr, LogQuery, logQueryDuration, LogSessionID)
    Values  (@Query, @time, @duration, @SessinID);
end;
GO

Derzeit befinden sich ungefähr 45500000 Zeilen in dieser Tabelle, und ich möchte die Protokollierung in eine andere Tabelle umleiten.

Meine Idee ist, das folgende Skript zu verwenden

begin Transaction

exec sp_rename LogTable, LogTableOld;

CREATE TABLE dbo.LogTable(
    LogRefnr int IDENTITY(46000000, 1) NOT NULL,            -- greater than select max(LogRefnr) from LogTableOld
    LogQuery varchar(255) NOT NULL,
    LogTime datetime NOT NULL,
    logQueryDuration int NULL,
    LogSessionID int NULL,
 CONSTRAINT PK_Log2 PRIMARY KEY CLUSTERED  (LogRefnr);
)
go

sp_recompile LogTable;
go

Commit;

Funktioniert dies und hat minimale Auswirkungen auf andere Prozeduren, die LogInsert aufrufen?

bernd_k
quelle
2
Sie brauchen das sp_recompile nicht. Der Prozedurcache für alle Objekte, die das Objekt dbo.LogTable verwenden, läuft automatisch ab, wenn Sie das Objekt umbenennen.
Mrdenny

Antworten:

24

Ja. Transaktionen gelten für DDL- und Spannenstapel.

Ich würde so etwas machen. Beachten Sie die Verwendung von SERIALIZABLE ISOLATION, um eine vollständige Isolation sicherzustellen, und von XACT_ABORT, wodurch bei Fehlern ein Rollback erzwungen wird.

SET XACT_ABORT ON
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
begin Transaction
GO
exec sp_rename LogTable, LogTableOld;
GO
CREATE TABLE dbo.LogTable(
    LogRefnr int IDENTITY(46000000, 1) NOT NULL,            -- greater than select max(LogRefnr) from LogTableOld
    LogQuery varchar(255) NOT NULL,
    LogTime datetime NOT NULL,
    logQueryDuration int NULL,
    LogSessionID int NULL,
 CONSTRAINT PK_Log2 PRIMARY KEY CLUSTERED  (LogRefnr);
)
go
EXEC sp_recompile LogTable;
go

Commit;
gbn
quelle
1
Können Sie auf eine Referenz verweisen, die zeigt, dass SQL Server-Transaktionen für DDL- und Span-Batches gelten? Die offensichtlichen BOL-Seiten erwähnen dies nicht.
Nick Chammas
2
@ Nick: Ich habe noch nie nach einem gesucht. Ich weiß, dass es funktioniert, wenn ich es die ganze Zeit benutze. Es liegt an Ihnen, mir zu glauben oder mich zu widerlegen oder es selbst zu versuchen. Natürlich sind Transaktionen pro Verbindung wie verschiedene der von mir verwendeten gesetzten Anweisungen. Eine Verbindung besteht aus mehreren Chargen. Was brauchst du noch?
5.
Ich glaube Ihnen, aber ich habe auf eine "offizielle" Dokumentation gehofft, die alle Aktionen auflistet, die an explizite Transaktionen gebunden sind und welche nicht. Beispielsweise sind Tabellenvariablen von Transaktions-Rollbacks nicht betroffen (was für mich gegen das Prinzip der geringsten Überraschung verstößt ).
Nick Chammas
2
Fast derselbe Code, aber die Transaktion funktioniert nicht: stackoverflow.com/questions/47868213/…
aleyush