Руководство по Spring. Управление транзакциями.

Когда мы работаем с базами данных (далее – БД), то обычно чаще всего нам необходимо выполнить одно из 4 действий: создать, прочитать, изменить либо удалить (для этого набора действий существует аббревиатура CRUD – Create Read Update Delete). Если мы хотим выполнить одно из таких действий нам необходимо выполнить транзакцию. Когда мы говорим о транзакциях в контексте БД, то мы имеем в виду последовательность действий с конечным количеством операций для достижения определённой цели, которая рассматривается как единое целое. Другими словами, если одна из операций в последовательности не выполнена, то вся последовательность считается не выполненной. Управление транзакциями является важной частью любой системой управления базой данных (далее – СУБД), оно обеспечивает целостность и однозначность данных.

Основные концепции транзакции описываются аббревиатурой ACID – Atomicity, Consistency, Isolation, Durability (Атомарность, Согласованность, Изолированность, Долговечность).


Атомарность

Атомарность гарантирует, что любая транзакция будет зафиксирована только целиком (полностью). Если одна из операций в последовательности не будет выполнена, то вся транзакция будет отменена. Тут вводится понятие “отката” (rollback). Т.е. внутри последовательности будут происходить определённые изменения, но по итогу все они будут отменены (“откачены”) и по итогу пользователь не увидит никаких изменений.


Согласованность

Это означает, что любая завершённая транзакция (транзакция, которая достигла завершения транзакции – end of transaction) фиксирует только допустимые результаты. Например, при переводе денег с одного счёта на другой, в случае, если деньги ушли с одного счёта, они должны прийти на другой (это и есть согласованность системы). Списание и зачисление  – это две разные транзакции, поэтому первая транзакция пройдёт без ошибок, а второй просто не будет. Именно поэтому крайне важно учитывать это свойство и поддерживать баланс системы.


Изолированность

Каждая транзакция должна быть изолирована от других, т.е. её результат не должен зависеть от выполнения других параллельных транзакций. На практике, изолированность крайне труднодостижима вещь, поэтому здесь вводится понятие “уровни изолированности” (транзакция изолируется не полностью).


Долговечность

Эта концепция гарантирует, что если мы получили подтверждение о выполнении транзакции, то изменения, вызванные этой транзакцией не должны быть отменены из-за сбоя системы (например, отключение электропитания).


В реальной жизни любая качественная СУБД поддерживает все эти 4 концепции для каждой транзакции. Если рассмотреть транзакцию упрощённо, то транзакция (при работе с SQL) выглядит примерно так:

  • Пользователь начинает транзакцию, используя команду “начать транзакцию” (begin transatcion);
  • Системы выполняют операцию создания, изменения или удаления используя SQL-запрос;
  • В случае, если все операции успешны, выполняется операция “выполнить” (commit). Если есть ошибка – выполняется откат всех операций (rollback);

Для различных API управления транзакциями Spring поддерживает  абстрактный слой. Spring добавляет возможность транзакций для POJO (Plain Old Java Object – простые старые java-объекты).

Виды управления транзакциями в Spring

поддерживает 2 вида управления транзакциями:

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

В случае декларативного управления транзакциями мы отделяем бизнес-логику от управления транзакциями. Мы используем либо аннотации, либо XML-файл для конфигурации управления транзакциями.

На практике, чаще всего используется декларативный метод управления транзакциями. Хоть этот метод и менее гибкий, чем программный, он может быть модульным (как и AOP). Стоит отметить, что декларативный метод реализован с помощью модуля АОП.

Spring является альтернативой EJB, который требует сервер для запуска приложения, в то время как управление транзакциями в Spring может быть реализовано без сервера приложения.

Абстракции транзакций в Spring

Главные абстракции транзакций в Spring определены в интерфейсе PlatformTransactionManager, который находится в пакете org.springframework.transaction.

В нём указаны 3 метода:

TransactionStatus getTransaction(TransactionDefinition definition);

Этот метод возвращает текущую активную транзакцию, либо создаёт новую в соответствии с определением.


void commit(TransactionStatus status);

Этот метод выполняет транзакцию в соответствии с её статусом.


void rollback(TransactionStatus status);

Этот метод выполняет откат транзакции.


Интерфейс TransactionDefinition включает в себя 5 методов


int getPropagationBehavior()

Возвращает метод распространения.


int getIsolationLevel()

Возвращает уровень изолирования.


String getName()

Возвращает имя транзакции.


int getTimeout()

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


boolean isReadOnly()

Метод возвращает логическое значение (true или false) доступен ли файл исключительно для чтения.

И наш крайний ключевой интерфейс TransactionStatus, который обеспечивает простой способ контроля за статусом выполнения транзакции. В нём определены следующие методы:

boolean hasSavepoint()
Этот метод возвращает логическое значение, имеет ли данная транзакция точку сохранения.


boolean isCompleted()

Возвращает логическое значение завершена ли данная транзакция (успешно завершена, либо выполнен откат).


boolean isNewTransaction()

Возвращает логическое значение, является ли текущая транзакция новой.


boolean isRollbackOnly()

Возвращает логическое значение, была ли эта транзакция отмечена, как rollback-only.


void setRollbackOnly()

Этот метод устанавливает параметр транзакции rollback-only.


В этой статье мы ознакомились с основами управления транзакциями в Spring Framework.