Первые транзакции: BEGIN, COMMIT, ROLLBACK
Курс MS SQL с нуля · Урок 11 из 12 · Часть 4. Запросы как инструмент
Транзакция — договор «всё или ничего»: пакет изменений либо записывается целиком, либо откатывается без следа. Урок безопасной глубины: ручной контроль в одной консоли, откат как привычка.
Внимание: урок меняет данные TechStore и работает в режиме Tx: Manual. Конец занятия — с @@TRANCOUNT в нуле и пересозданием базы скриптами урока 2. Гонки сеансов оставлены продвинутому курсу.
Содержание
1. Что вы освоите
К концу урока вы:
- объявляете пакет изменений атомарным через BEGIN TRAN и COMMIT;
- откатываете цепочку целиком ROLLBACK-ом и знаете его грубость;
- работаете в режиме Tx: Manual в DataGrip осознанно;
- сверяете @@ROWCOUNT и @@TRANCOUNT как приборы консоли;
- наблюдаете блокировку вторым сеансом и объясняете её механику.
2. BEGIN TRAN, COMMIT, ROLLBACK
Чистый код
BEGIN TRAN;
UPDATE p SET StockQty = StockQty - 1
FROM dbo.Products AS p
WHERE p.ProductID = 42;
SELECT StockQty FROM dbo.Products WHERE ProductID = 42;
COMMIT;
- Построчный разбор
Ниже приведён тот же фрагмент с пояснением после каждой смысловой строки. Строки, которые начинаются с двух дефисов и стрелки вправо, содержат комментарий преподавателя. Эти строки не являются обязательной частью программы.
BEGIN TRAN; -- → транзакцию открывают до первого изменения, не после UPDATE p SET StockQty = StockQty - 1 FROM dbo.Products AS p WHERE p.ProductID = 42; -- → списание одного остатка; пока видимо только этому сеансу SELECT StockQty FROM dbo.Products WHERE ProductID = 42; -- → взгляд до COMMIT: состояние проверяется глазами COMMIT; -- → записать навсегда; альтернатива — ROLLBACK, отменить целиком; -- → оба оператора сразу недопустимы: Msg 3903SQL
- пока транзакция открыта, изменение видно лишь своему сеансу: другие видят старые значения — простейшая демонстрация изоляции;
- @@TRANCOUNT — число открытых транзакций сеанса; после COMMIT и ROLLBACK — ноль;
- забытая открытая транзакция держит блокировки — механика «всё повисло» другой консоли.
3. Режим Tx в DataGrip
На верхней панели консоли DataGrip — переключатель Tx: Auto или Manual. В Auto каждый оператор — самодостаточная микротранзакция с автоподтверждением; в Manual операторы накапливаются, пока не нажмёте зелёную галочку Commit или красный крест Rollback.
Режим лабораторий урока
Manual и только он
Все задачи урока выполняются в Tx: Manual: это единственный способ откатить уже выполненный UPDATE взглядом на панели. Перед началом переключатель проверяется глазами, а в конце занятия возвращается в Auto вместе с проверкой @@TRANCOUNT = 0.
Вложенность и грубость ROLLBACK
Чистый код
BEGIN TRAN;
SELECT @@TRANCOUNT AS depth1;
BEGIN TRAN;
SELECT @@TRANCOUNT AS depth2;
COMMIT;
SELECT @@TRANCOUNT AS depth3;
ROLLBACK;
SELECT @@TRANCOUNT AS depth4;
GO
- Построчный разбор
Ниже приведён тот же фрагмент с пояснением после каждой смысловой строки. Строки, которые начинаются с двух дефисов и стрелки вправо, содержат комментарий преподавателя. Эти строки не являются обязательной частью программы.
BEGIN TRAN; SELECT @@TRANCOUNT AS depth1; -- → глубина один: первый BEGIN открыл цепочку BEGIN TRAN; SELECT @@TRANCOUNT AS depth2; -- → глубина два: вложенный BEGIN лишь наращивает счётчик COMMIT; SELECT @@TRANCOUNT AS depth3; -- → COMMIT уменьшил счётчик до единицы: цепочка жива ROLLBACK; SELECT @@TRANCOUNT AS depth4; -- → ROLLBACK гасит всю цепочку разом, счётчик в нуле GOSQL
Вывод лаборатории: COMMIT уменьшает счётчик на единицу, а ROLLBACK сводит цепь целиком к нулю: вложенные COMMIT безопасны, вложенные ROLLBACK — грубые. Точечный возврат внутри пакета — SAVE TRAN — тема продвинутого урока.
↑ К оглавлению4. Перестраховочный паттерн
Перестраховочный паттерн массового изменения из четырёх шагов:
- SELECT с предикатом — считает и показывает строки цели;
- BEGIN TRAN и UPDATE тем же предикатом; сверка @@ROWCOUNT с прогнозом;
- взгляд на выборку после изменения;
- COMMIT только когда три числа сошлись; иначе ROLLBACK.
5. Задачи и эталонные решения
Шесть задач на контексте TechStore, все — в одной консоли с Tx: Manual. Вторая консоль понадобится с задачи 11.5.
- покупка товара атомарным пакетом: остаток минус один плюс строка заказа, один COMMIT в конце;
- намеренный откат: категория 5 дешевеет на девяносто процентов, осмотр, ROLLBACK; в журнал комментариями — @@ROWCOUNT и @@TRANCOUNT;
- двойной COMMIT: вторая попытка падает с Msg 3902, номер записывается в журнал;
- лаборатория вложенности: два BEGIN подряд, счётчики, единый ROLLBACK и вывод;
- взгляд извне: пока первая консоль держит изменение открытым, вторая читает те же строки; наблюдения записываются;
- зависшая песочница: первая консоль «забыла» транзакцию, вторая меняет ту же строку, пять секунд ожидания, стоп, откат первой.
Эталон задачи 11.1
пакет подтверждается одним COMMIT
Чистый код
BEGIN TRAN;
UPDATE p SET StockQty = StockQty - 1
FROM dbo.Products AS p
WHERE p.ProductID = 42;
INSERT dbo.OrderItems (OrderID, ProductID, Quantity, UnitPrice)
SELECT (SELECT MAX(x.OrderID) FROM dbo.Orders AS x), 42, 1, p.Price
FROM dbo.Products AS p
WHERE p.ProductID = 42;
SELECT StockQty FROM dbo.Products WHERE ProductID = 42;
COMMIT;
GO
- Построчный разбор
Ниже приведён тот же фрагмент с пояснением после каждой смысловой строки. Строки, которые начинаются с двух дефисов и стрелки вправо, содержат комментарий преподавателя. Эти строки не являются обязательной частью программы.
BEGIN TRAN; -- → пакет из двух изменений становится атомарным UPDATE p SET StockQty = StockQty - 1 FROM dbo.Products AS p WHERE p.ProductID = 42; -- → первый шаг: списание остатка INSERT dbo.OrderItems (OrderID, ProductID, Quantity, UnitPrice) SELECT (SELECT MAX(x.OrderID) FROM dbo.Orders AS x), 42, 1, p.Price FROM dbo.Products AS p WHERE p.ProductID = 42; -- → второй шаг: учебная позиция в последний заказ по цене каталога SELECT StockQty FROM dbo.Products WHERE ProductID = 42; -- → сверка глазами: сошлось, подтверждаем; не сошлось — ROLLBACK COMMIT; GOатомарность пакета
6. Типичные ошибки урока
- BEGIN после UPDATE — транзакция началась после изменения; изменение прошло мимо неё. BEGIN ставится первым.
- ROLLBACK после COMMIT — Msg 3903: транзакцию завершают один раз и осмысленно.
- Auto-режим в лаборатории — изменение подтвердилось само; переключатель Tx проверяется взглядом до начала.
- Открытая транзакция на ночь — цепочка блокировок в боевой базе; правило курса: конец лаборатории — проверка @@TRANCOUNT = 0.
- ROWCOUNT на глазах — «выглядит правдоподобно» не приём; число сравнивается с прогнозом SELECT вслух.
- ROLLBACK якобы на один шаг — ROLLBACK гасит всю цепочку; точечный возврат — SAVE TRAN, тема продвинутого курса.
7. Чек-лист практики и источники
Чек-лист урока 11
отметки делаются по факту
Источники для углубления:
Проверено: 23.10.2026
↑ К оглавлению