java / intermediate
Snippet
Conditional Programmatic Rollback Control via TransactionAspectSupport
Declarative Spring transactions (`@Transactional`) roll back by default only on unchecked runtime exceptions. When business logic requires a transaction rollback without throwing an exception—such as returning a structured domain response indicating fraud—calling `TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()` cleanly flags the ongoing transaction for rollback during control flow evaluation.
snippet.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Servicepublic class PaymentProcessingService {private final LedgerRepository ledgerRepository;private final ExternalPaymentGateway paymentGateway;@Transactionalpublic ProcessingResult processTransaction(PaymentRequest request) {LedgerEntry entry = ledgerRepository.save(new LedgerEntry(request.getAmount()));GatewayResponse response = paymentGateway.charge(request.getPaymentMethod(), request.getAmount());if (response.getStatus() == GatewayStatus.SUSPECTED_FRAUD) {TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();return ProcessingResult.flaggedForReview(entry.getId(), response.getReason());}entry.markSettled(response.getTransactionId());return ProcessingResult.success(entry.getId());}}
spring
Breakdown
1
@Transactional
Opens a managed database transaction boundary surrounding the entire method execution.
2
if (response.getStatus() == GatewayStatus.SUSPECTED_FRAUD) {
Evaluates the business logic condition that demands aborting data persistence.
3
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
Directs the active Spring transaction manager to roll back on method completion without throwing an exception.
4
return ProcessingResult.flaggedForReview(entry.getId(), response.getReason());
Allows the method to return a standard result object gracefully despite database rollback.