У меня есть хранимая процедура, которая должна установить точку сохранения, чтобы при определенных обстоятельствах она могла отменить все, что она сделала, и вернуть код ошибки вызывающей стороне, или принять / зафиксировать ее и вернуть ее успешной. Но мне нужно, чтобы он работал независимо от того, начал ли абонент уже транзакцию или нет. Док крайне запутан в этом вопросе. Вот то, что я думаю, сработает, но я не уверен во всех последствиях.
Дело в том - это Stored Procedure (SP)
вызывается другими. Так что я не знаю, начали ли они транзакцию или нет ... Даже если я требую, чтобы пользователи начали транзакцию, чтобы использовать мой SP, у меня все еще есть вопросы о правильном использовании Save Points
...
Мой SP проверит, выполняется ли транзакция, и если нет, начните ее с BEGIN TRANSACTION
. Если транзакция уже выполняется, вместо этого она создаст точку сохранения с SAVE TRANSACTION MySavePointName
и сохранит тот факт, что это то, что я и сделал.
Тогда, если мне придется откатить свои изменения, если я сделал BEGIN TRANSACTION
ранее, то я ROLLBACK TRANSACTION
. Если я сделал точку сохранения, то я ROLLBACK TRANSACTION MySavePointName
. Этот сценарий, кажется, работает отлично.
Здесь я немного запутался - если я захочу продолжить работу, которую я проделал, если я начну транзакцию, я выполню COMMIT TRANSACTION
. Но если я создал точку сохранения? Я попытался COMMIT TRANSACTION MySavePointName
, но затем вызывающая сторона пытается зафиксировать свою транзакцию и получает ошибку:
У запроса COMMIT TRANSACTION нет соответствующей BEGIN TRANSACTION.
Так что мне интересно - точка возврата может быть откатана (это работает: ROLLBACK TRANSACTION MySavePointName
НЕ откатит транзакцию вызывающего). Но, возможно, никогда не нужно «совершать» это? Он просто остается там, на случай, если вам нужно откатиться к нему, но уходит, когда исходная транзакция зафиксирована (или откатана)?
Если есть «лучший» способ «вложить» транзакцию, пожалуйста, пролите немного света. Я не понял, как вложить с BEGIN TRANSACTION
, а только откатил или зафиксировал мою внутреннюю транзакцию. Кажется, ROLLBACK
всегда будет возвращаться к верхней транзакции, в то время как COMMIT
просто уменьшает @@trancount
.