Какой смысл в «ROLLBACK TRANSACTION named_transaction»? - PullRequest
6 голосов
/ 28 ноября 2009

Я прочитал через MSDN на ROLLBACK TRANSACTION и вложенных транзакций . Хотя я вижу смысл ROLLBACK TRANSACTION savepointname, я не понимаю ROLLBACK TRANSACTION transactionname.

  1. Работает только тогда, когда transactionname является самой внешней транзакцией
  2. ROLLBACK всегда откатывает всю «стопку» транзакций, кроме случая savepointname

Обычно, когда я читаю документацию, за исключением случая сохранения, ROLLBACK откатывает все транзакции (до @@TRANCOUNT=0). Единственное отличие, которое я вижу, это фрагмент:

Если оператор транзакции ROLLBACK TRANSACTION с именем внешняя транзакция выполняется на любом уровне множества вложенных транзакции, все вложенные транзакции откатываются. Если оператор ROLLBACK WORK или ROLLBACK TRANSACTION без Параметр транзакция_имя выполняется на любом уровне множества вложенных транзакция, она откатывает все вложенные транзакции, включая самая внешняя транзакция.

Из прочтенного мне следует, что при откате именованной транзакции (которая должна быть именем самой внешней транзакции) будут откатываться только вложенные транзакции. Это придаст смысл откату именованной транзакции. Итак, я настроил тест:

CREATE TABLE #TEMP (id varchar(50))

INSERT INTO #TEMP (id) VALUES ('NO')
SELECT id AS NOTRAN FROM #TEMP
SELECT @@TRANCOUNT AS NOTRAN_TRANCOUNT

BEGIN TRAN OUTERTRAN

INSERT INTO #TEMP (id) VALUES ('OUTER')
SELECT id AS OUTERTRAN FROM #TEMP
SELECT @@TRANCOUNT AS OUTERTRAN_TRANCOUNT

BEGIN TRAN INNERTRAN

INSERT INTO #TEMP (id) VALUES ('INNER')
SELECT id AS INNERTRAN FROM #TEMP
SELECT @@TRANCOUNT AS INNERTRAN_TRANCOUNT

ROLLBACK TRAN OUTERTRAN

IF @@TRANCOUNT > 0 ROLLBACK TRAN

SELECT id AS AFTERROLLBACK FROM #TEMP
SELECT @@TRANCOUNT AS AFTERROLLBACK_TRANCOUNT

DROP TABLE #TEMP

В результате (все "X строки затронуты" удалены)

NOTRAN
--------------------------------------------------
NO

NOTRAN_TRANCOUNT
----------------
0

OUTERTRAN
--------------------------------------------------
NO
OUTER

OUTERTRAN_TRANCOUNT
-------------------
1

INNERTRAN
--------------------------------------------------
NO
OUTER
INNER

INNERTRAN_TRANCOUNT
-------------------
2

AFTERROLLBACK
--------------------------------------------------
NO

AFTERROLLBACK_TRANCOUNT
-----------------------
0

Обратите внимание, что при изменении

на выходе не будет никакой разницы
ROLLBACK TRAN OUTERTRAN

просто

ROLLBACK TRAN

Так в чем смысл ROLLBACK TRANSACTION <b>named_transaction</b>?

1 Ответ

5 голосов
/ 29 ноября 2009

Точки сохранения в точности соответствуют названию: «точки сохранения» в последовательности журнала. Логарифмическая последовательность всегда линейна. Если вы выполняете откат до точки сохранения, вы откатываете все , в котором выполнялась транзакция между текущей позицией журнала и точкой сохранения. Рассмотрим ваш пример:

LSN 1: BEGIN TRAN OUTERTRAN
LSN 2: INSERT INTO ...
LSN 3: BEGIN TRAN INNERTRAN
LSN 4: INSERT INTO ...
LSN 5: ROLLBACK TRAN OUTERTRAN

При порядковом номере журнала (LSN) 1 создается точка сохранения OUTERTRAN. Первый INSERT создает LSN 2. Затем INNERTRAN создает точку сохранения с LSN 3. Второй INSERT создает новый LSN 4. ROLLBACK OUTERTRAN эквивалентен «ROLLBACK log до LSN 1». Вы не можете «пропустить» части журнала, поэтому необходимо откатывать каждую операцию в журнале, пока не будет достигнут LSN 1 (когда была создана точка сохранения OUTERTRAN).

С другой стороны, если при последней операции вы запускаете ROLLBACK INNERTRAN, двигатель будет откатываться до тех пор, пока LSN 3 (где точка сохранения 'INNERTRAN' была вставлена ​​в журнал), таким образом, сохранит LSN 1 и LSN 2 (т.е. первая ВСТАВКА).

Практический пример точек сохранения см. Обработка исключений и вложенные транзакции .

...