Transactions with @Transactional

Hibernate · lesson 6 of 32 · 4 min read

Use Spring transactions properly and avoid the two mistakes that silently disable them.

Open this lesson in the learning hub

Key points

  • A persistence context lives and dies with a transaction. No transaction means no dirty checking and no lazy loading.
  • Annotate the service method that represents one unit of work, not every repository call.
  • Spring wraps the bean in a proxy. Calling an annotated method from inside the same class skips the proxy, so no transaction starts.
  • Rollback is automatic for RuntimeException and Error only. For a checked exception you must add rollbackFor.
  • readOnly = true skips dirty-checking work and hints the database. Use it on every query-only method.
  • Keep transactions short. An HTTP call inside one holds a database connection hostage for its whole duration.

Example

@Service
public class OrderService {

    private final OrderRepository orders;
    private final StockService stock;

    OrderService(OrderRepository orders, StockService stock) {
        this.orders = orders;
        this.stock = stock;
    }

    @Transactional
    public Order place(Long customerId, String sku, int qty) {
        stock.reserve(sku, qty);                 // same transaction
        return orders.save(new Order(customerId, sku, qty));
    }

    @Transactional(readOnly = true)
    public List<Order> recent(Long customerId) {
        return orders.findTop10ByCustomerIdOrderByCreatedAtDesc(customerId);
    }

    @Transactional(rollbackFor = PaymentDeclinedException.class)
    public void charge(Long orderId) throws PaymentDeclinedException {
        // checked exceptions do NOT roll back unless you say so
    }
}

One transaction per unit of work, and it has to be entered from outside the bean.

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 Hibernate course, and every lesson in it is listed on the Hibernate contents page.