2011-01-06 1 views
6

Если у меня есть хранимая процедура, которая несколько раз выполняет другую хранимую процедуру с разными аргументами, возможно ли, чтобы каждый из этих вызовов совершал независимую от других?Как я могу гарантировать, что вложенные транзакции совершаются независимо друг от друга?

Другими словами, если первые два выполнения вложенной процедуры успешны, но третий не удался, можно ли сохранить результаты первых двух исполнений (а не отбросить их назад)?

Я хранимая процедура, определенная что-то вроде этого в SQL Server 2000:

CREATE PROCEDURE toplevel_proc .. 
AS 
BEGIN 

     ... 

     while @row_count <= @max_rows 
    begin 
     select @parameter ... where rownum = @row_count 
     exec nested_proc @parameter 
     select @row_count = @row_count + 1 
    end 

END 

ответ

6

Во-первых, there is no such thing as a nested transaction in SQL Server

Однако, вы можете использовать SAVEPOINTs согласно этому примеру (слишком долго, чтобы воспроизвести здесь извините) от пользователя SO пользователя Remus Rusanu

Редактировать: Алексей Кузнецов упомянул (хотя он удалил свой ответ), что это не сработает, если сделка обречена. Это может произойти с SET XACT_ABORT ON или некоторыми ошибками запуска.

3

От BOL:

ROLLBACK TRANSACTION без savepoint_name или transaction_name катится назад в начале сделки. Когда вложенные транзакции, это же заявление откатывает все внутренние транзакции до внешняя инструкция BEGIN TRANSACTION .

я нашел следующее из другого потока here:

Имейте в виду, что транзакции SQL Server не очень вложенными, как вы могли подумать . После начала транзакции Explode , последующий BEGIN TRAN увеличивает @@ TRANCOUNT , в то время как COMMIT уменьшает значение. Вся основная транзакция - , совершенная, когда результат COMMIT равен zero @@ TRANCOUNT. Но ROLLBACK без точки сохранения откатывает все Работа, включая внешний сделка.

Если вам нужно вложенное поведение транзакции , вам необходимо использовать SAVE TRANSACTION вместо НАЧАТЬ TRAN и использования ROLLBACK TRAN [savepoint_name] вместо ROLLBACK TRAN.

Так что это представляется возможным.

+1

"использовать ROLLBACK TRAN вместо ROLLBACK TRAN" ?? – Greg

+0

@Greg - спасибо, что указали это. Текст, который я цитировал, использовал угловые скобки вокруг текста 'savepoint_name', и это заставило механизм разметки SO скрыть текст. Изменили текст, чтобы использовать квадратные скобки. – Tony

+0

Спасибо за исправление! – Greg