#java #spring #transactions
#java #spring #транзакции
Вопрос:
Обработка транзакций — это обработка информации в информатике, которая разделена на отдельные, неделимые операции, называемые транзакциями. Каждая транзакция должна быть успешной или завершаться неудачей как целостная единица; она никогда не может быть завершена только частично.
Обработка транзакций предназначена для поддержания целостности системы в известном, согласованном состоянии, гарантируя, что все взаимозависимые операции в системе либо успешно завершены, либо все успешно отменены. Википедия
При управлении транзакциями в Spring мы могли бы использовать модификатор rollbackFor.
Основной целью этого модификатора является:
Определяет ноль (0) или более классов исключений, которые должны быть подклассами Throwable, указывая, какие типы исключений должны вызывать откат транзакции.
Я нашел метод, подобный этому :
@Transactional(rollbackFor = {SubscriptionException.class}, transactionManager = "txManager")
public void subscription(User user) throws SubscriptionException {
operationA(user);
operationB(user); // could throw a SubscriptionException
operationC(user);
}
В случае operationC
сбоя изменения, внесенные operationA
и operationB
, сохранятся. ИМХО, свойство «Атомарности» концепции ACID нарушено в этой транзакции.
Как обеспечить концепцию ACID, когда мы используем модификатор rollbackFor
для транзакционной аннотации Spring?
Комментарии:
1. Установив значение rollbackFor в SubscriptionException.class вы точно решили, что никакое другое исключение, кроме SubscriptionException, не является сбоем. Итак, если C «терпит неудачу», это означает, что is выдает исключение SubscriptionException, и все будет откатываться. Если он выдает другое исключение, то оно не завершается сбоем, потому что только исключение SubscriptionException является сбоем. Если вы хотите, чтобы другие исключения представляли собой сбой, добавьте их в rollbackFor .
2. «Если операция C завершается с ошибкой, изменения, внесенные operationA и operationB, сохранятся». Нет, если операции являются транзакционными.
3. @JBNizet «что никакое другое исключение, кроме исключения SubscriptionException, не является сбоем» Неверно. Javadoc of
@Transactional
говорит: «Если никакие правила не относятся к исключению, оно будет обрабатываться как DefaultTransactionAttribute ( откат наRuntimeException
иError
, но не на проверенные исключения )» . — ПосколькуSubscriptionException
это единственное возможное проверяемое исключение, этот код будет откатываться на все исключения.4. @Andreas если вы не укажете rollbackFor, то исключения и ошибки во время выполнения вызовут откат. Если вы это сделаете, то исключения, указанные в rollbackFor, вызовут откат.
5.@JBNizet
rollbackFor
добавляет правило. Тогда «Если никакие правила не относятся к исключению, …» означает, что правила отката по умолчанию дляRuntimeException
иError
по-прежнему применяются. Если вы не хотите, чтобы все или некоторые исключения RuntimeExceptions выполняли откат, вам нужно назвать их с помощьюnoRollbackFor
.