СОХРАНИТЬ ТРАНЗАКЦИЮ и НАЧАТЬ ТРАНЗАКЦИЮ (SQL Server), как правильно вкладывать транзакции

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

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

Мой SP проверит, выполняется ли транзакция, и если нет, запустит ее с помощью BEGIN TRANSACTION. Если транзакция уже выполняется, она вместо этого создаст точку сохранения с SAVE TRANSACTION MySavePointNameи сохранит тот факт, что я и сделал.

Затем, если мне придется откатить свои изменения, если я сделал НАЧАТЬ ТРАНЗАКЦИЮранее, я ОТМЕНЯЮ ТРАНЗАКЦИЮ. Если я сделал точку сохранения, то я ROLLBACK TRANSACTION MySavePointName. Этот сценарий, кажется, отлично работает.

Здесь я немного запутался — если я хочу сохранить проделанную работу, если я начал транзакцию, я выполню COMMIT TRANSACTION. А если бы я создал точку сохранения? Я попробовал COMMIT TRANSACTION MySavePointName, но затем вызывающий объект пытается зафиксировать свою транзакцию и получает сообщение об ошибке:

Запросу COMMIT TRANSACTION не соответствует BEGIN TRANSACTION.

Тогда мне интересно, точку сохранения можно откатить (это работает: ROLLBACK TRANSACTION MySavePointNameНЕ будет откатывать транзакцию вызывающей стороны). Но, может быть, никогда не нужно «совершать» это? Он просто остается там на случай, если вам нужно будет откатиться к нему, но исчезает, когда исходная транзакция фиксируется (или откатывается)?

Если есть «лучший» способ «вложить» транзакцию, расскажите, пожалуйста. Я не понял, как вложить с помощью BEGIN TRANSACTION, а только откатить или зафиксировать мою внутреннюю транзакцию. Кажется, ROLLBACKвсегда будет выполнять откат к верхней транзакции, тогда как COMMITпросто уменьшает @@trancount.

15
задан StuartLC 17 October 2017 в 05:07
поделиться