Как создать хранимую процедуру, эффекты которой нельзя откатить? - PullRequest
4 голосов
/ 12 сентября 2011

Я хочу иметь хранимую процедуру, которая вставляет запись в таблицу A и обновляет записи в таблице B.

Хранимая процедура будет вызываться изнутри триггера.

Я хочу, чтобы вставленные записи в таблице A существовали, даже если откат самой внешней транзакции триггера.

Записи в таблице A связаны линейно, и я должен иметь возможность восстановить линейное соединение.

Доступ на запись в таблицу A возможен только через триггеры.

Как мне это сделать?

Ответы [ 3 ]

9 голосов
/ 12 сентября 2011

Вам нужны автономные транзакции, которых сегодня нет в SQL Server. Пожалуйста, проголосуйте / прокомментируйте следующие пункты:

http://connect.microsoft.com/SQLServer/feedback/details/296870/add-support-for-autonomous-transactions

http://connect.microsoft.com/SQLServer/feedback/details/324569/add-support-for-true-nested-transactions

То, что вы можете рассмотреть, это использовать xp_cmdshell или CLR для выхода за пределы механизма SQL, чтобы вернуться (эти действия не могут быть отменены SQL Server) ... но эти методы не обходятся без собственных проблем.

Другая идея состоит в том, чтобы использовать триггеры INSTEAD OF - вы можете регистрировать / обновлять другие таблицы, а затем просто принять решение не выполнять фактическое действие.

EDIT

И в соответствии с предложением @ VoodooChild вы можете использовать переменную @table для временного хранения данных, на которые вы можете ссылаться после отката - эти данные выдержат откат, в отличие от вставки в #temp table.

5 голосов
/ 12 сентября 2011

См. Этот пост Регистрация сообщений во время транзакции для (несколько запутанного) эффективного способа достижения того, что вы хотите: вставка в таблицу журналов сохраняется, даже если транзакция откатилась. Метод, который предлагает Саймон, имеет несколько преимуществ: не требует никаких изменений для вызывающей стороны, является быстрым и масштабируемым, и его можно безопасно использовать из триггера. Пример Саймона для ведения журнала, но вставка может быть для чего угодно.

4 голосов
/ 12 сентября 2011

Один из способов - создать связанный сервер, который указывает на локальный сервер.Хранимые процедуры, выполненные на связанном сервере, не будут откатываться:

EXEC LinkedServer.DbName.dbo.sp_LogInfo 'this won''t be rolled back'

Вы можете вызвать удаленную хранимую процедуру из триггера.

...