Транзакции
Конструкция Transaction выполняет блок операций с базой данных в одной
транзакции. Платформа сама начинает транзакцию, фиксирует её при успешном
завершении блока и откатывает при исключении.
Similar Pascal
Transaction
Begin
(Insert Into Orders(Name) Values('Заказ'));
(Update Counters Set Value = Value + 1 Where Name = 'Orders');
End;
По умолчанию используется уровень изоляции Serializable. Уровень можно
указать после слова Transaction:
Transaction Read Uncommitted
Begin
...
End;
Transaction Read Committed
Begin
...
End;
Transaction Repeatable Read
Begin
...
End;
Similar Basic
Transaction
(Insert Into Orders(Name) Values('Заказ'))
(Update Counters Set Value = Value + 1 Where Name = 'Orders')
End Transaction
Уровни изоляции задаются так же, как в Similar Pascal. Конструкция
Transaction для Similar C пока не реализована.
Commit и rollback
Управление транзакцией выполняется автоматически:
| Завершение блока | Действие платформы |
|---|---|
| Выполнение дошло до конца блока | COMMIT |
| Из блока вышло исключение | ROLLBACK, затем исключение передаётся выше |
Публичных команд Commit и Rollback в прикладном языке нет. Не следует
отправлять их вручную как SQL: платформа ведёт собственный уровень вложенности,
и прямой SQL нарушит его состояние.
Чтобы программно отменить транзакцию, нужно выбросить исключение:
Try
Transaction
Begin
(Update Accounts Set Balance = Balance - 100 Where Id = 1);
If Not OperationIsValid Then
Raise('Операция отменена');
End;
Except
Warning(GetExceptionText());
End;
Внешний Except выполняется уже после отката. Если исключение перехвачено
внутренним Try/Except непосредственно внутри Transaction и не выброшено
повторно, блок считается успешно завершённым и будет зафиксирован.
Вложенные транзакции
Вложенные блоки используют одну физическую транзакцию и счётчик вложенности.
Это не savepoint и не независимая транзакция. Фактический COMMIT выполняется
при завершении самого внешнего блока. Не следует использовать вложенный блок
для частичного отката.
Уровень изоляции задаёт внешний блок. Запрос более строгого уровня во вложенном блоке не начинает новую транзакцию и может привести к предупреждению.
Ограничения
- Транзакция относится только к операциям текущего подключения к базе данных. HTTP-запросы, файлы и другие внешние действия не откатываются.
- Возможность отката зависит от СУБД и типа таблицы. Например, MySQL DDL и нетранзакционные таблицы могут фиксировать изменения независимо от блока.
- Не используйте
ExitилиReturnдля выхода из серединыTransaction. Завершайте блок штатно либо выбрасывайте исключение черезRaise.