Регистрация TSQL внутри транзакции - PullRequest
17 голосов
/ 16 ноября 2010

Я пытаюсь записать в файл журнала внутри транзакции, чтобы журнал сохранился, даже если транзакция откатывается.

- начальный код

begin trans

вставить [что-то] в dbo.logtable

[[основной код здесь]]

откат

коммит

- код конца

Вы могли бы сказать, просто ведите журнал до начала транзакции, но это не так просто, потому что транзакция начинается до запуска этого S-Proc (т. Е. Код является частью более крупной транзакции)

ИтакКороче говоря, есть ли способ написать специальное заявление внутри транзакции, которая не является частью транзакции.Я надеюсь, что мой вопрос имеет смысл.

Ответы [ 5 ]

13 голосов
/ 16 ноября 2010

Используйте переменную таблицы (@temp) для хранения информации журнала.Табличные переменные выдерживают откат транзакции.

См. эту статью .

8 голосов
/ 16 ноября 2010

См. Регистрация сообщений во время транзакции для альтернативного решения на основе sp_trace_generateevent, для которого не требуется переменная scope @table (что не всегда возможно) или когда транзакцияграницы находятся вне контроля.

2 голосов
/ 16 ноября 2010

Я делаю это одним из двух способов, в зависимости от моих потребностей в данный момент. Оба включают использование переменной, которая сохраняет свое значение после отката.

1) Создайте значение DECLARE @Log varchar(max) и используйте это: @SET @ Log = ISNULL (@ Log + ';', '') + 'Ваш новый журнал информации здесь' . Keep appending to this as you go through the transaction. I'll insert this into the log after the commit or the rollback as necessary. I'll usually only insert the @Log value into the real log table when there is an error (in the CATCH` блок) или If I ' я пытаюсь отладить проблему.

2) создать DECLARE @LogTable table (RowID int identity(1,1) primary key, RowValue varchar(5000). Я вставляю это по мере прохождения транзакции. Мне нравится использовать предложение OUTPUT для вставки фактических идентификаторов (и других столбцов с сообщениями, например, «УДАЛИТЬ элемент 1234») строк, используемых в транзакции, в эту таблицу с. Я добавлю эту таблицу в фактическую таблицу журнала после фиксации или отката по мере необходимости.

1 голос
/ 16 ноября 2010

Если родительская транзакция откатывается, данные журналирования также будут откатываться - сервер SQL не поддерживает правильные вложенные транзакции.Одной из возможностей является использование хранимой процедуры CLR для ведения журнала.Это может открыть собственное соединение с базой данных вне транзакции и ввести и зафиксировать данные журнала.

0 голосов
/ 23 декабря 2015

Если вы хотите эмулировать поведение вложенных транзакций, вы можете использовать именованные транзакции:

begin transaction a

create table #a (i  int)

select * from #a
save transaction b

create table #b (i  int)
select * from #a
select * from #b

rollback transaction b

select * from #a
rollback transaction a

В SQL Server, если вам нужна «суб-транзакция», вы должны использовать save transaction xxxx, которая работает как контрольная точка оракула. ​​

...