Использование транзакций с выделенным пулом SQL в Azure Synapse Analytics
Советы по реализации транзакций с выделенным пулом SQL в Azure Synapse Analytics для разработки решений.
Чего следует ожидать
Как можно ожидать, выделенный пул SQL поддерживает транзакции как часть рабочей нагрузки хранилища данных. Однако для поддержания производительности выделенного пула SQL на соответствующем уровне некоторые возможности ограничиваются по сравнению с SQL Server. Эта статья посвящена отличиям этого продукта от аналогичных систем.
Уровни изоляции транзакций
Выделенный пул SQL реализует транзакции ACID. Уровень изоляции транзакционной поддержки по умолчанию — READ UNCOMMITTED. Его можно изменить на READ COMMITTED SNAPSHOT ISOLATION, включив параметр базы данных READ_COMMITTED_SNAPSHOT для пользовательской базы данных при подключении к базе данных master.
После его включения все транзакции в этой базе данных выполняются в режиме READ COMMITTED SNAPSHOT ISOLATION, и параметр READ UNCOMMITTED на уровне сеанса учитываться не будет. Дополнительные сведения см. в разделе Параметры ALTER DATABASE SET (Transact-SQL).
Размер транзакции
Размер одной транзакции, изменяющей данные, ограничен. Действует ограничение по распределению. Поэтому можно вычислить общие выделенные ресурсы, перемножив величины ограничения и распределения.
Чтобы приблизительно определить максимальное количество строк в транзакции, разделите величину ограничения распределения на значение общего размера каждой строки. Для столбцов переменной длины рекомендуется брать среднюю длину столбца, а не максимальный размер.
В таблице ниже были сделаны следующие допущения:
- выполнено равномерное распределение данных;
- средняя длина строки составляет 250 байтов.
Поколение 2
DWU | Ограничение распределения (ГБ) | Число распределений | Максимальный размер транзакции (ГБ) | # Число строк в распределении | Максимальное число строк на транзакцию |
---|---|---|---|---|---|
DW100c | 1 | 60 | 60 | 4 000 000 | 240 000 000 |
DW200c | 1.5 | 60 | 90 | 6 000 000 | 360 000 000 |
DW300c | 2.25 | 60 | 135 | 9 000 000 | 540 000 000 |
DW400c | 3 | 60 | 180 | 12 000 000 | 720 000 000 |
DW500c | 3,75 | 60 | 225 | 15 000 000 | 900 000 000 |
DW1000c | 7.5 | 60 | 450 | 30 000 000 | 1 800 000 000 |
DW1500c | 11,25 | 60 | 675 | 45 000 000 | 2 700 000 000 |
DW2000c | 15 | 60 | 900 | 60 000 000 | 3 600 000 000 |
DW2500c | 18,75 | 60 | 1125 | 75 000 000 | 4 500 000 000 |
DW3000c | 22,5 | 60 | 1350 | 90 000 000 | 5 400 000 000 |
DW5000c | 37,5 | 60 | 2,250 | 150 000 000 | 9 000 000 000 |
DW6000c | 45 | 60 | 2700 | 180 000 000 | 10 800 000 000 |
DW7500c | 56,25 | 60 | 3,375 | 225 000 000 | 13 500 000 000 |
DW10000c | 75 | 60 | 4 500 | 300 000 000 | 18 000 000 000 |
DW15000c | 112,5 | 60 | 6750 | 450 000 000 | 27 000 000 000 |
DW30000c | 225 | 60 | 13 500 | 900 000 000 | 54 000 000 000 |
Поколение 1
DWU | Ограничение распределения (ГБ) | Число распределений | Максимальный размер транзакции (ГБ) | # Число строк в распределении | Максимальное число строк на транзакцию |
---|---|---|---|---|---|
DW100 | 1 | 60 | 60 | 4 000 000 | 240 000 000 |
DW200 | 1.5 | 60 | 90 | 6 000 000 | 360 000 000 |
DW300 | 2.25 | 60 | 135 | 9 000 000 | 540 000 000 |
DW400 | 3 | 60 | 180 | 12 000 000 | 720 000 000 |
DW500 | 3,75 | 60 | 225 | 15 000 000 | 900 000 000 |
DW600 | 4.5. | 60 | 270 | 18 000 000 | 1 080 000 000 |
DW1000 | 7.5 | 60 | 450 | 30 000 000 | 1 800 000 000 |
DW1200 | 9 | 60 | 540 | 36 000 000 | 2 160 000 000 |
DW1500 | 11,25 | 60 | 675 | 45 000 000 | 2 700 000 000 |
DW2000 | 15 | 60 | 900 | 60 000 000 | 3 600 000 000 |
DW3000 | 22,5 | 60 | 1350 | 90 000 000 | 5 400 000 000 |
DW6000 | 45 | 60 | 2700 | 180 000 000 | 10 800 000 000 |
Ограничение размера транзакции накладывается на транзакцию или операцию. Оно не применяется к совокупности параллельных транзакций. Поэтому каждая транзакция может записать такой объем данных в журнал.
Сведения об оптимизации и минимизации объема данных, записываемых в журнал, см. в статье Оптимизация транзакций для хранилища данных SQL.
Предупреждение
Максимальный размер транзакции может быть достигнут только для распределенных таблиц HASH или ROUND_ROBIN, где распределение данных равномерно. Если транзакция неравномерно записывает данные в распределения, то вполне вероятно, что ограничение будет достигнуто до того, как размер транзакции станет максимальным.
Состояние транзакции
Выделенный пул SQL использует функцию XACT_STATE() со значением -2, чтобы сообщить о неудачной транзакции. Это означает, что произошел сбой транзакции и она помечена только для отката.
Примечание
Использование функцией XACT_STATE значения -2 для обозначения неудачной транзакции отличается от поведения в SQL Server. SQL Server для представления нефиксируемой транзакции использует значение -1. SQL Server может допускать некоторые ошибки внутри транзакции, не помечая ее как нефиксируемую. Например, SELECT 1/0
вызовет ошибку, но не приведет к переходу транзакции в состояние нефиксируемой. SQL Server также разрешает чтение в нефиксируемой транзакции. Однако выделенный пул SQL не позволяет это сделать. При возникновении ошибки в транзакции выделенного пула SQL транзакция автоматически перейдет в состояние -2, и вы не сможете выполнить дополнительные инструкции SELECT, пока не произойдет откат этой инструкции. Поэтому важно проверить код приложения, чтобы определить, используется ли в нем 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;
В предыдущем коде появляется следующее сообщение об ошибке:
Сообщение 111233, уровень 16, состояние 1, строка 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_ * предоставляют значения, как ожидалось.
Изменилось всего лишь то, что операция ROLLBACK с транзакцией должна произойти до чтения информации об ошибке в блоке CATCH.
Функция Error_Line()
Также следует отметить, что выделенный пул SQL не реализует и не поддерживает функцию ERROR_LINE(). Если эта функция используется в коде, ее необходимо удалить, чтобы обеспечить совместимость с выделенным пулом SQL. Вместо этого используйте в коде метки запросов, чтобы реализовать эквивалентную функциональность. Дополнительные сведения см. в статье LABEL.
Использование THROW и RAISERROR
THROW — это более современная реализация вызова исключений в выделенном пуле SQL, но RAISERROR также поддерживается. Тем не менее, существует ряд различий, которые заслуживают внимания.
- Для THROW номера определяемых пользователем сообщений об ошибках не могут быть в диапазоне от 100 000 до 150 000.
- Номера сообщений об ошибках RAISERROR не должны превышать 50 000.
- Не поддерживается использование sys.messages.
Ограничения
В выделенном пуле SQL есть несколько ограничений, относящихся к транзакциям. Вот они:
- не поддерживаются распределенные транзакции;
- вложенные транзакции не разрешены;
- не допускается точки сохранения.
- не допускаются именованные транзакции;
- не допускаются помеченные транзакции;
- не поддерживаются операторы DDL, такие как CREATE TABLE, внутри определенной пользователем транзакции.
Дальнейшие действия
Узнайте больше об оптимизации транзакций, ознакомившись со статьей Оптимизация транзакций для хранилища данных SQL. Дополнительные рекомендации также предоставляются для выделенного пула SQL и бессерверного пула SQL.