Precise transaction control in an e-commerce application relies on @Transactional to guarantee that multi-step operations, like placing an order and charging payment, either fully succeed or fully roll back.
Key Points: • @Transactional on the order-placement service method ensures inventory deduction, order creation, and payment recording happen atomically. • Configure rollbackFor to include checked exceptions if you need rollback on more than just unchecked exceptions (the default). • Isolation level and propagation should be chosen deliberately -- e.g. REQUIRED for steps that must join the same transaction. • For workflows spanning multiple independent services (payment service, inventory service), a single database transaction isn't possible, so a saga pattern with compensating actions is used instead. • Keep transactions short-lived to avoid holding database locks during slow operations like external payment gateway calls.
Example: If payment processing fails after inventory has already been decremented within the same @Transactional method, Spring rolls back the inventory change automatically, preventing a customer from being charged without ever reducing stock levels, or vice versa.
Code Example:
@Transactional(rollbackFor = PaymentException.class)
public Order placeOrder(OrderRequest request) {
inventoryService.reserve(request.getItems());
Order order = orderRepository.save(new Order(request));
paymentService.charge(request.getPaymentInfo());
return order;
}Interview Tip: A concise interview answer is:
"I'd wrap the order-placement logic in @Transactional so inventory update, order creation, and payment recording either all commit or all roll back together. For workflows that span separate microservices, I'd move to a saga pattern with compensating transactions, since a single ACID transaction can't span multiple databases."