Як використовувати транзакції з DDL SQL Server?


20

У мене є таблиця входу, в яку всі вставки виконуються за єдиною збереженою процедурою.

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

Наразі в цій таблиці близько 45500000 рядків, і я хочу направити журнал до іншої таблиці.

Моя ідея - використовувати наступний сценарій

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;

Чи працює це і має мінімальний вплив на інші процедури, що викликають LogInsert?


2
Sp_recompile вам не потрібен. Кеш процедур для будь-яких об'єктів, які використовують об'єкт dbo.LogTable, автоматично закінчується, коли ви перейменовуєте об'єкт.
mrdenny

Відповіді:


24

Так. Операції стосуються пакетів DDL та проміжного періоду.

Я б зробив щось подібне. Зверніть увагу на використання СЕРІАЛІЗАЦІЙНОЇ ІЗОЛЯЦІЇ для забезпечення повної ізоляції та XACT_ABORT, що призведе до відкату будь-якої помилки.

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
Чи можете ви зв’язатись із посиланням, що показує, що транзакції SQL Server застосовуються до пакетів DDL та span? Ця очевидні сторінки BOL не згадують про це.
Nick Chammas

2
@Nick: Я ніколи її не шукав. Я знаю, що це працює, коли я його постійно використовую. Ви повинні мені повірити чи спростувати мене або спробувати це на собі. Звичайно, транзакції проводяться за з'єднання, як і різні набір операторів, які я використовую. З'єднання складається з декількох партій. Що ще вам потрібно?
gbn

Я вірю вам, але я сподівався на якусь "офіційну" документацію, яка перелічує всі дії, які пов'язані з явними транзакціями, а які - ні. Наприклад, на змінні таблиці не впливають відкати на транзакції (що, на мій погляд, порушує Принцип найменшого сюрпризу ).
Нік Чаммас

2
Майже той же код, але угода не працює: stackoverflow.com/questions/47868213 / ...
aleyush
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.