java 41 lines · 6 steps

How @Transactional guards a Spring checkout

A Spring service coordinates inventory, payment, and loyalty in one atomic transaction that rolls back on any failure.

Explained by highlit
1@Service
2public class OrderCheckoutService {
3 
4 private final OrderRepository orderRepository;
5 private final InventoryRepository inventoryRepository;
6 private final PaymentGateway paymentGateway;
7 private final LoyaltyService loyaltyService;
8 
9 public OrderCheckoutService(OrderRepository orderRepository,
10 InventoryRepository inventoryRepository,
11 PaymentGateway paymentGateway,
12 LoyaltyService loyaltyService) {
13 this.orderRepository = orderRepository;
14 this.inventoryRepository = inventoryRepository;
15 this.paymentGateway = paymentGateway;
16 this.loyaltyService = loyaltyService;
17 }
18 
19 @Transactional
20 public Order checkout(CheckoutRequest request) {
21 Order order = orderRepository.save(Order.pending(request.customerId()));
22 
23 for (LineItem item : request.items()) {
24 int remaining = inventoryRepository.decrementStock(item.sku(), item.quantity());
25 if (remaining < 0) {
26 throw new InsufficientStockException(item.sku());
27 }
28 order.addLine(item);
29 }
30 
31 PaymentResult payment = paymentGateway.charge(request.customerId(), order.totalAmount());
32 if (!payment.approved()) {
33 throw new PaymentDeclinedException(payment.declineCode());
34 }
35 
36 order.markPaid(payment.transactionId());
37 loyaltyService.awardPoints(request.customerId(), order.totalAmount());
38 
39 return orderRepository.save(order);
40 }
41}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Wrapping a multi-step workflow in @Transactional makes any thrown exception roll back every prior write automatically.
  2. 2Constructor injection keeps collaborators final and makes the service's dependencies explicit and testable.
  3. 3Throwing domain exceptions mid-flow is the mechanism that aborts the whole transaction rather than leaving partial state.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How @Transactional guards a Spring checkout — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code