Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье содержатся советы по реализации транзакций и разработке решений в пуле SQL.
Чего следует ожидать
Как ожидается, пул SQL поддерживает транзакции в рамках рабочей нагрузки хранилища данных. Тем не менее, чтобы пул SQL сохранялся в большом масштабе, некоторые функции ограничены при сравнении с SQL Server. В этой статье рассматриваются различия.
Уровни изоляции транзакций
Пул SQL реализует транзакции ACID. Уровень изоляции поддержки транзакций по умолчанию установлен на "READ UNCOMMITTED". Его можно изменить на READ COMMITTED SNAPSHOT ISOLATION, включив параметр базы данных READ_COMMITTED_SNAPSHOT для пользовательского пула SQL при подключении к базе данных master.
После включения этой настройки все транзакции в этой базе данных выполняются в режиме 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, и вы не сможете выполнять дальнейшие инструкции 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;
Приведенный выше код содержит следующее сообщение об ошибке:
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.