Transactions with @Transactional

Spring Boot · lesson 20 of 39 · 4 min read

Commit several writes as one unit, and learn which exceptions actually roll back.

Open this lesson in the learning hub

Key points

  • Put @Transactional on the service method so several repository calls commit or fail together.
  • Only RuntimeException and Error roll back. A checked exception commits unless you add rollbackFor.
  • Catching the exception inside the method hides it from the proxy, and the transaction then commits happily.
  • readOnly = true lets Hibernate skip dirty checking and lets the driver route to a replica.
  • Default propagation REQUIRED joins the caller transaction; REQUIRES_NEW suspends it and opens another.
  • Keep transactions short. Never make a remote HTTP call while a database connection is held open.

Example

@Service
public class CheckoutService {

    @Transactional                    // one unit: both writes, or neither
    public Order checkout(long cartId) {
        Cart cart = carts.findById(cartId).orElseThrow(CartNotFoundException::new);
        stock.reserve(cart.items());                  // UPDATE stock
        Order order = orders.save(Order.from(cart));   // INSERT order
        return order;                 // the commit happens at this boundary
    }

    @Transactional(rollbackFor = ExportFailedException.class)   // checked: opt in
    public void exportDaily() throws ExportFailedException {
        /* ... */
    }

    @Transactional(readOnly = true)   // no dirty checking, no flush
    public List<Order> history(String email) {
        return orders.findByCustomerEmail(email);
    }

    @Transactional
    public void swallowed(long id) {
        try {
            risky(id);
        } catch (RuntimeException ex) {
            log.warn("ignored", ex);  // the proxy never sees it, so this COMMITS
        }
    }
}

The transaction ends at the boundary of the annotated method - and only an unchecked exception rolls it back.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Spring Boot course, and every lesson in it is listed on the Spring Boot contents page.