logo

Использование команды GO в SQL транзакции: решение ошибок

Быстрый ответ

Транзакция объединяет набор связанных операций в единый действенный блок. Оператор GO в свою очередь, представляет собой сигнал о завершении пакета SQL-команд. Именно поэтому применение GO в рамках одной транзакции недопустимо: это будет сопровождаться автоматическим завершением транзакции. Для частичного отката используйте механизм вложенных транзакций и сохраняющих точек.

Пример правильного использования без GO:

SQL
Скопировать код
BEGIN TRANSACTION;
INSERT INTO TableA VALUES (1, 'A');
UPDATE TableB SET Column = 'B' WHERE ID = 1;
COMMIT TRANSACTION;

Что такое GO?

Клоунада с разделителями пакетов

Шутки в сторону, но GO — это не команда T-SQL, а разделитель пакетов для SQL Server Management Studio (SSMS) и утилиты sqlcmd. Он служит указанием на то, что следующий блок кода будет выполнен отдельно. Помните, что применение GO в теле транзакции аналогично просьбе предъявить счет до подачи блюда: пакет закоммитит или откатит все открытые транзакции, не дождавшись их завершения.

sqlcmd и osql: Дуэт мускулистов

Через командную строку с использованием инструментов sqlcmd или osql вы можете управлять разбиением скриптов на отдельные пакеты:

batch
Скопировать код
sqlcmd -i myscript.sql -o output.txt

SET XACT_ABORT: Супергерой без маски

Применяйте SET XACT_ABORT ON, чтобы убедиться, что в случае ошибок операции будут автоматически откачены, обеспечивающее сохранение целостности данных:

SQL
Скопировать код
SET XACT_ABORT ON;
BEGIN TRANSACTION;
-- Здесь ваши команды T-SQL
COMMIT TRANSACTION;

Приручение «GO»льяна

Или избегайте применения GO во время проведения транзакций, или структурируйте код таким образом, чтобы корректно использовать GO, сохраняя целостность транзакционной логики.

Визуализация

Совершение транзакции без GO напоминает непрерывное путешествие. С GO может случиться, что путешествие разобьется на отдельные несвязанные этапы.

Завершение

Присвоение имен вашим транзакциям

Назначайте имена транзакциям для удобства ориентации и управления в сложных скриптах:

SQL
Скопировать код
BEGIN TRANSACTION MyTran;
-- Код, связанный с транзакцией MyTran
IF @@ERROR <> 0
    ROLLBACK TRANSACTION MyTran;
COMMIT TRANSACTION MyTran;

Область видимости и управление переменными

Структурируйте ваш код T-SQL таким образом, чтобы переменные не теряли свою область видимости, избегайте применения GO в телах транзакций.

Поддержание порядка в пакетах

Если в одном из пакетов возникает ошибка, откатывайте всю транзакцию, дабы сохранить согласованность данных.

Альтернативное управление транзакциями

Применяйте альтернативные способы контроля над транзакциями, как например ExecuteNonQuery() или создание CLR хранимых процедур.

csharp
Скопировать код
using (var transaction = connection.BeginTransaction())
{
    try
    {
        // Вызовы ExecuteNonQuery 
    }
    catch (Exception)
    {
        transaction.Rollback();
        throw;
    }
}

Полезные материалы

  1. Объективный обзор транзакций SQL Server от компании Microsoft.
  2. Распространенные ошибки при разработке баз данных, с которыми сталкиваются разработчики.
  3. Подробное руководство по SQL Server и его пакетной обработке.