Ответ 1
Используйте переменную таблицы (@temp) для хранения информации журнала. Переменные таблицы сохраняют откат транзакций.
См. эту статью.
Я пытаюсь записать в файл журнала внутри транзакции, чтобы журнал сохранялся, даже если транзакция откат.
- стартовый код
begin tran
вставить [something] в dbo.logtable
[[основной код здесь]]
откат
совершают
- конечный код
Вы можете сказать, что просто выполните журнал до начала транзакции, но это не так просто, потому что транзакция начинается до запуска этого S-Proc (т.е. код является частью более крупной транзакции).
Итак, вкратце, есть ли способ написать специальный оператор внутри транзакции, которая не является частью транзакции. Надеюсь, мой вопрос имеет смысл.
Используйте переменную таблицы (@temp) для хранения информации журнала. Переменные таблицы сохраняют откат транзакций.
См. эту статью.
См. Запись сообщений во время транзакции для альтернативного решения на основе sp_trace_generateevent
, который не требует переменной scope @table (что не всегда возможно) или когда границы транзакций находятся вне контроля.
Я делаю это одним из двух способов, в зависимости от моих потребностей в то время. Оба включают использование переменной, которая сохраняет свое значение после отката.
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 я ' m пытается отладить проблему.
2) создайте DECLARE @LogTable table (RowID int identity(1,1) primary key, RowValue varchar(5000)
. Я вставляю это, когда вы продвигаетесь по транзакции. Мне нравится использовать предложение OUTPUT
, чтобы вставить фактические идентификаторы (и другие столбцы с сообщениями, такими как "DELETE item 1234" ) строк, используемых в транзакции в эту таблицу. Я вставляю эту таблицу в фактическую таблицу журналов после фиксации или отката по мере необходимости.
Если родительская транзакция откатывается, данные каротажа также откатываются назад - сервер SQL не поддерживает правильные вложенные транзакции. Одна из возможностей заключается в использовании хранимой процедуры CLR для ведения журнала. Это может открыть собственное подключение к базе данных вне транзакции и ввести и зафиксировать данные журнала.
Если вы хотите эмулировать поведение вложенных транзакций, вы можете использовать именованные транзакции:
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
, которая работает как контрольная точка oracle.