2014-10-07 2 views
5

К моей проблеме: я вызываю хранимую процедуру из своего бизнес-кода. Этот вызов находится в явной транзакции. Хранимая процедура иногда вызывает другую, чтобы что-то записать в базу данных. Эти данные должны оставаться в базе данных, даже когда транзакция откатывается. Аналогичный сценарий - это когда вы хотите что-то записать в таблице журналов, и сообщение журнала должно храниться (это не мое дело, это просто аналогичное требование).Можно ли исключить хранимую процедуру из транзакции в MS SQL?

Как я могу исключить вторую хранимую процедуру из внешней транзакции? Я думаю, что я ищу что-то вроде «автономных транзакций» в Oracle. Я искал возможную эмуляцию, но все решения выглядели не очень «красиво» (создайте loopback-сервер, добавьте некоторые .NET-методы, ...)

Любые идеи? Спасибо!

+0

Вы видели это: http://blogs.msdn.com/b/sqlprogrammability/archive/2008/08/22/how-to-create-an-autonomous-transaction-in-sql-server-2008. aspx – Mohammadreza

ответ

0

Насколько я знаю, вы не можете исключать конкретные операции из транзакций, содержащих их. Моим подходом было бы попытаться явно сделать то, что вы хотите сделать, вместо того, чтобы откатить всю транзакцию. Или, если это вариант, откат транзакции, а затем повторно запустите хранимую процедуру, которую вы не хотите откатывать.

+0

Спасибо, но это невозможно. Хранимые процедуры довольно велики, они могут вызвать хранимую процедуру для хранения некоторой информации несколько раз. Эта информация должна храниться там, но все другие возможные изменения должны отменяться, когда что-то происходит. – Raul

1

Нет такого изящного решения проблемы этого типа, хотя это кажется обычным явлением. Все между begin transaction и commit или rollback сделано в целом. Вы не можете просто вставить строку в таблицу журналов, например, и сохранить ее после rollback.

Но вы можете сделать некоторые трюки.

1) Вызовите свою процедуру с помощью xp_cmdshell, чтобы вызвать OSQL.exe. Производительность будет плохой, но внешние команды не участвуют в транзакции, и ничто не мешает вам выполнять внешние операторы SQL.

2) в хранимой процедуре вы можете добавить записи в переменную таблицы вместо реальной таблицы. Табличные переменные не участвуют в транзакции, так как они не изменяют базу данных. После этого добавьте содержимое переменной в свою таблицу, когда вы закрыли транзакцию в любом случае.

3) Если вы не можете изменить внутреннюю процедуру, вы можете извлечь записи (записи), которые она, возможно, создала, в переменную таблицы после вызова, но из транзакции с неподвижным открытием. Откат транзакции и добавление извлеченных записей в таблицу снова.

Смежные вопросы