Понимание 1 правильно. SQL Server записывает каждую операцию, которая изменяет данные, в журнал транзакций. Откат - это изменение данных, поэтому он также записывает это в журнал транзакций. При выполнении оператора A он записывает данные в журнал транзакций, а также резервирует данные в журнале транзакций на случай, если необходимо выполнить откат оператора A. То же самое верно для B и C. При откате транзакции дополнительная информация будет записана в журнал.
Есть много способов увидеть это в действии, поэтому ниже приведена краткая демонстрация. Вот запрос, который я буду использовать, чтобы увидеть, что было записано в журнал:
SELECT
COUNT(*) transaction_count
, SUM(database_transaction_log_bytes_used) used_bytes
, SUM(database_transaction_log_bytes_reserved) reserved_bytes
FROM sys.dm_tran_database_transactions
where database_id = 10;
Мой стол:
create table TLOGDEMO (FLUFF VARCHAR(1000));
BEGIN TRANSACTION
Запрос A использует минимальное ведение журнала:
INSERT INTO TLOGDEMO WITH (TABLOCK)
SELECT REPLICATE('A', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
После:
╔═══════════════════╦════════════╦════════════════╗
║ transaction_count ║ used_bytes ║ reserved_bytes ║
╠═══════════════════╬════════════╬════════════════╣
║ 1 ║ 24006640 ║ 175429451 ║
╚═══════════════════╩════════════╩════════════════╝
Запрос B не использует минимальное ведение журнала:
INSERT INTO TLOGDEMO
SELECT REPLICATE('B', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
После Б:
╔═══════════════════╦════════════╦════════════════╗
║ transaction_count ║ used_bytes ║ reserved_bytes ║
╠═══════════════════╬════════════╬════════════════╣
║ 1 ║ 7352935708 ║ 1613986255 ║
╚═══════════════════╩════════════╩════════════════╝
Запрос C изменяет меньше данных:
INSERT INTO TLOGDEMO
SELECT REPLICATE('C', 1000)
FROM master..spt_values c;
После C:
╔═══════════════════╦════════════╦════════════════╗
║ transaction_count ║ used_bytes ║ reserved_bytes ║
╠═══════════════════╬════════════╬════════════════╣
║ 1 ║ 7355821748 ║ 1614545331 ║
╚═══════════════════╩════════════╩════════════════╝
Теперь я буду выдавать ROLLBACKи запрашивать DMV, пока происходит откат. Ниже приведена таблица с несколькими снимками:
╔═══════════════════╦════════════╦════════════════╗
║ transaction_count ║ used_bytes ║ reserved_bytes ║
╠═══════════════════╬════════════╬════════════════╣
║ 1 ║ 7393305528 ║ 1573797677 ║
║ 1 ║ 7458767420 ║ 1502635737 ║
║ 1 ║ 7682482356 ║ 1259440979 ║
║ 1 ║ 7803881368 ║ 1127471233 ║
║ ... ║ ... ║ ... ║
╚═══════════════════╩════════════╩════════════════╝
В течение ROLLBACKэтого времени используемые байты увеличиваются, а зарезервированное количество байтов уменьшается. Это связано с тем, что SQL Server использует пространство, отведенное ранее для отмены транзакции. Чтобы отменить транзакцию, она должна изменить данные, чтобы записать больше данных в журнал.