Jak korzystać z transakcji za pomocą SQL Server DDL?


20

Mam tabelę logowania, w której wszystkie wstawki są wykonywane za pomocą jednej procedury składowanej.

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

Obecnie w tej tabeli znajduje się około 45500000 wierszy i chcę przekierować logowanie do innej tabeli.

Moim pomysłem jest użycie następującego skryptu

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;

Czy to działa i ma minimalny wpływ na inne procedury wywołujące LogInsert?


2
Nie potrzebujesz sp_recompile. Pamięć podręczna procedur dla wszystkich obiektów korzystających z obiektu dbo.LogTable wygaśnie automatycznie po zmianie nazwy obiektu.
mrdenny,

Odpowiedzi:


24

Tak. Transakcje dotyczą partii DDL i zakresów.

Zrobiłbym coś takiego. Zwróć uwagę na użycie SERIALIZABLE ISOLATION, aby zapewnić pełną izolację i XACT_ABORT, który wymusi wycofanie każdego błędu.

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;

1
Czy możesz połączyć się z odnośnikiem pokazującym, że transakcje SQL Server dotyczą partii DDL i zakresów? Do oczywistych strony BOL nie wspomnieć o tym.
Nick Chammas,

2
@Nick: Nigdy go nie szukałem. Ja wiem, że działa jak używam go cały czas. Do ciebie, byś mi uwierzył, obalił mnie lub wypróbował sam. Oczywiście transakcje dotyczą poszczególnych połączeń, podobnie jak różne zestawienia, których używam. Połączenie składa się z wielu partii. Czego więcej potrzebujesz?
gbn

Wierzę ci, ale liczyłem na jakąś „oficjalną” dokumentację, która wylicza wszystkie działania związane z jawnymi transakcjami, a które nie. Na przykład na zmienne tabeli nie ma wpływu wycofywanie transakcji (co, moim zdaniem, narusza zasadę najmniejszej niespodzianki ).
Nick Chammas,

2
Prawie ten sam kod, ale transakcja nie działa: stackoverflow.com/questions/47868213/...
aleyush,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.