Поделиться через


Использование транзакций с выделенным пулом SQL в Azure Synapse Analytics

Советы по реализации транзакций с выделенным пулом SQL в Azure Synapse Analytics для разработки решений.

Чего следует ожидать

Как ожидается, выделенный пул SQL поддерживает транзакции в рамках рабочей нагрузки хранилища данных. Однако, чтобы обеспечить производительность пула выделенных SQL в условиях масштабирования, некоторые возможности ограничены в сравнении с SQL Server. В этой статье рассматриваются различия и перечислены другие.

Уровни изоляции транзакций

Выделенный пул SQL реализует транзакции ACID. Уровень изоляции поддержки транзакций по умолчанию установлен на "READ UNCOMMITTED". Вы можете изменить уровень изоляции на READ COMMITTED SNAPSHOT ISOLATION, включив параметр базы данных READ_COMMITTED_SNAPSHOT для пользовательской базы данных при подключении к главной базе данных.

После включения этого режима все транзакции в данной базе данных выполняются в режиме READ COMMITTED SNAPSHOT ISOLATION, и установка READ UNCOMMITTED на уровне сеанса учитываться не будет. Для получения подробной информации проверьте параметры ALTER DATABASE SET (Transact-SQL) .

Размер транзакции

Одна транзакция изменения данных ограничена размером. Ограничение применяется для каждого распределения. Таким образом, общее выделение можно вычислить путем умножения предела на число распределения.

Чтобы приблизить максимальное количество строк в транзакции, разделите ограничение распределения на общий размер каждой строки. Для столбцов переменной длины рекомендуется принимать среднюю длину столбца, а не использовать максимальный размер.

В таблице ниже были сделаны следующие предположения:

  • Произошло равномерное распределение данных
  • Средняя длина строки составляет 250 байт

Gen2

DWU Лимит на распределение (ГБ) Количество распределений Максимальный размер транзакции (ГБ) # Строки для каждого распределения Максимальное количество строк на транзакцию
DW100c 1 шестьдесят шестьдесят 4 000 000 240,000,000
DW200c 1.5 шестьдесят девяносто 6 000 000 360 000 000
DW300c 2,25 шестьдесят 135 9,000,000 540,000,000
DW400c 3 шестьдесят 180 12,000,000 720,000,000
DW500c. 3,75 % шестьдесят 225 15 000 000 900,000,000
DW1000c 7.5 шестьдесят 450 30,000,000 1,800,000,000
DW1500c 11,25 шестьдесят 675 45,000,000 2,700,000,000
DW2000c 15 шестьдесят 900 60 000 000 3,600,000,000
DW2500c 18.75 шестьдесят 1125 75,000,000 4,500,000,000
DW3000c 22,5 шестьдесят 1350 90 000 000 5,400,000,000
DW5000c 37,5 шестьдесят 2,250 150,000,000 9,000,000,000
DW6000c 45 шестьдесят 2,700 180,000,000 10,800,000,000
DW7500c 56.25 шестьдесят 3375 225,000,000 13,500,000,000
DW10000c 75 шестьдесят 4 500 300 000 000 18,000,000,000
DW15000c 112,5 шестьдесят 6,750 450,000,000 27,000,000,000
DW30000c 225 шестьдесят 13,500 900,000,000 54,000,000,000

Ген1

DWU Лимит на распределение (ГБ) Количество распределений Максимальный размер транзакции (ГБ) # Строки для каждого распределения Максимальное количество строк на транзакцию
DW100 1 шестьдесят шестьдесят 4 000 000 240,000,000
DW200 1.5 шестьдесят девяносто 6 000 000 360 000 000
DW300 2,25 шестьдесят 135 9,000,000 540,000,000
DW400 3 шестьдесят 180 12,000,000 720,000,000
DW500 3,75 % шестьдесят 225 15 000 000 900,000,000
DW600 4,5 шестьдесят 270 18 000 000 1,080,000,000
DW10000 7.5 шестьдесят 450 30,000,000 1,800,000,000
DW1200 9 шестьдесят 540 36 000 000 2,160,000,000
DW1500 11,25 шестьдесят 675 45,000,000 2,700,000,000
DW2000 15 шестьдесят 900 60 000 000 3,600,000,000
DW30000 22,5 шестьдесят 1350 90 000 000 5,400,000,000
DW60000 45 шестьдесят 2,700 180,000,000 10,800,000,000

Ограничение размера транзакции применяется для каждой транзакции или операции. Он не применяется ко всем параллельным транзакциям. Поэтому каждая транзакция может записывать этот объем данных в журнал.

Чтобы оптимизировать и свести к минимуму объем данных, записанных в журнал, см. статью о рекомендациях по транзакциям .

Предупреждение

Максимальный размер транзакции можно достичь только для распределённых таблиц типа HASH или ROUND_ROBIN, где данные распределяются равномерно. Если транзакция записывает данные с перекосом в распределения, то предел, скорее всего, будет достигнут раньше максимального размера транзакции.

Состояние транзакции

Выделенный пул SQL использует функцию XACT_STATE(), чтобы сообщить о неудачной транзакции с помощью значения -2. Это значение означает, что транзакция завершилась сбоем и помечена для отката.

Примечание.

Использование -2 функцией XACT_STATE для обозначения неудачной транзакции представляет другое поведение SQL Server. SQL Server использует значение -1 для представления неуправляемой транзакции. SQL Server может допустить некоторые ошибки внутри транзакции без необходимости помечать её как неподлежащей фиксации. Например, SELECT 1/0 приведет к ошибке, но не переводит транзакцию в несохраняемое состояние. SQL Server также позволяет считывать данные в неподтверждённой транзакции. Однако выделенный пул SQL не позволяет сделать это. Если ошибка возникает внутри транзакции в выделенном пуле SQL, она автоматически перейдет в состояние -2, и вы не сможете выполнять дальнейшие инструкции выбора, пока транзакция не будет отменена. Поэтому важно проверить, использует ли код приложения XACT_STATE(), так как может потребоваться внести изменения кода.

Например, в SQL Server может появиться транзакция, которая выглядит следующим образом:

SET NOCOUNT ON;
DECLARE @xact_state smallint = 0;

BEGIN TRAN
    BEGIN TRY
        DECLARE @i INT;
        SET     @i = CONVERT(INT,'ABC');
    END TRY
    BEGIN CATCH
        SET @xact_state = XACT_STATE();

        SELECT  ERROR_NUMBER()    AS ErrNumber
        ,       ERROR_SEVERITY()  AS ErrSeverity
        ,       ERROR_STATE()     AS ErrState
        ,       ERROR_PROCEDURE() AS ErrProcedure
        ,       ERROR_MESSAGE()   AS ErrMessage
        ;

        IF @@TRANCOUNT > 0
        BEGIN
            ROLLBACK TRAN;
            PRINT 'ROLLBACK';
        END

    END CATCH;

IF @@TRANCOUNT >0
BEGIN
    PRINT 'COMMIT';
    COMMIT TRAN;
END

SELECT @xact_state AS TransactionState;

Приведенный выше код содержит следующее сообщение об ошибке:

Msg 111233, Level 16, State 1, Line 1 111233; Текущая транзакция прервана, и все ожидающие изменения были откатены. Причина: транзакция, находящаяся в состоянии только для отката, не была явно завершена откатом до выполнения операции DDL, DML или SELECT.

Выходные данные функций ERROR_* не будут отображаться.

В выделенном пуле SQL код должен быть немного изменен:

SET NOCOUNT ON;
DECLARE @xact_state smallint = 0;

BEGIN TRAN
    BEGIN TRY
        DECLARE @i INT;
        SET     @i = CONVERT(INT,'ABC');
    END TRY
    BEGIN CATCH
        SET @xact_state = XACT_STATE();

        IF @@TRANCOUNT > 0
        BEGIN
            ROLLBACK TRAN;
            PRINT 'ROLLBACK';
        END

        SELECT  ERROR_NUMBER()    AS ErrNumber
        ,       ERROR_SEVERITY()  AS ErrSeverity
        ,       ERROR_STATE()     AS ErrState
        ,       ERROR_PROCEDURE() AS ErrProcedure
        ,       ERROR_MESSAGE()   AS ErrMessage
        ;
    END CATCH;

IF @@TRANCOUNT >0
BEGIN
    PRINT 'COMMIT';
    COMMIT TRAN;
END

SELECT @xact_state AS TransactionState;

Теперь наблюдается ожидаемое поведение. Ошибка в транзакции корректируется, и функции ERROR_* предоставляют значения, как и ожидалось.

Единственное, что изменилось, это то, что откат транзакции должен был произойти до того, как было бы прочитано сообщение об ошибке в блоке CATCH.

функция Error_Line()

Также следует отметить, что выделенный пул SQL не реализует или поддерживает функцию ERROR_LINE(). Если у вас есть эта функция в коде, необходимо удалить ее для соответствия выделенному пулу SQL. Вместо этого используйте метки запросов в коде, чтобы реализовать эквивалентные функциональные возможности. Дополнительные сведения см. в статье LABEL .

Использование THROW и RAISERROR

THROW — это более современная реализация для создания исключений в выделенном пуле SQL, но также поддерживается RAISERROR. Есть несколько различий, на которые стоит обратить внимание.

  • Определяемые пользователем номера сообщений об ошибках не могут находиться в диапазоне 100 000 – 150 000 для THROW.
  • Сообщения об ошибках RAISERROR установлены на значение 50 000.
  • Использование sys.messages не поддерживается

Ограничения

Выделенный пул SQL имеет несколько других ограничений, связанных с транзакциями. Они приведены следующим образом:

  • Нет распределенных транзакций
  • Не разрешены вложенные транзакции
  • Нет разрешенных точек сохранения
  • Без именованных транзакций
  • Нет помеченных транзакций
  • Нет поддержки DDL, например CREATE TABLE внутри определяемой пользователем транзакции

Дальнейшие действия

Чтобы узнать больше об оптимизации транзакций, см. в разделе Рекомендации по лучшим практикамтранзакций. Дополнительные рекомендации также предоставляются для выделенного пула SQL и бессерверного пула SQL.