DEV Community

Sayuri Kotikawaththa
Sayuri Kotikawaththa

Posted on

Stop Killing Your Database with @Transactional in Spring Boot

The 1-minute fix that slashed my API response time by 40%.

We all know @Transactional makes database work easy. But are you using it correctly?

Here is a mistake I see in 8 out of 10 code reviews:

โŒ The Anti-Pattern:

@Service
public class OrderService {
    @Transactional
    public Order placeOrder(OrderDto dto) {
        Order order = new Order();
        // 1. Save the parent
        orderRepository.save(order);

        // 2. Loop and save children one by one
        for (Item i : dto.getItems()) {
            Item item = new Item();
            item.setOrder(order);
            itemRepository.save(item); // ๐Ÿ’€ N+1 problem + multiple flush calls
        }
        return order;
    }
}
Enter fullscreen mode Exit fullscreen mode

The Problem: Even with @Transactional, calling .save() in a loop forces Hibernate to hit the database for every single item. Thatโ€™s 50 round trips for 50 items.

โœ… The Game-Changer:
Use Batch Insertion with a simple property change.

1.Add this to application.properties:

spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
Enter fullscreen mode Exit fullscreen mode

2.Refactor your code to use .saveAll():

@Transactional
public Order placeOrder(OrderDto dto) {
    Order order = new Order();
    orderRepository.save(order); // Save parent first

    List<Item> items = dto.getItems().stream()
        .map(i -> new Item(i, order))
        .collect(Collectors.toList());

    itemRepository.saveAll(items); // ONE single INSERT statement for all items!

    return order;
}
Enter fullscreen mode Exit fullscreen mode

The Result:

  • Before: 51 SQL queries for 50 items.
  • After: 2 SQL queries for 50 items.
  • Performance: 40% faster response time.
  • DB Load: Drastically reduced.

The takeaway: @Transactional manages the transaction, but it doesn't batch your queries. You have to explicitly tell Hibernate to batch them.

Discussion Question: What's the one Spring Boot property you can't live without? Drop it in the comments! ๐Ÿ‘‡

Top comments (0)