0

How to force update bean in Transactional & Async Method in spring boot? I want it to save immediately at specific point and not at the end of the transactional function

import javax.transaction.Transactional;

@Service
@Transactional
public class CustomerServiceImpl implements CustomerService {

    @Autowired
    private CustomerRepository customerRepository;

    @Override
    @Async
    public void sendAllWithQueryParam(Customer customer) {
        // some code
        customerRepository.save(customer);
        // extre code
    }
}

Also note that, when I added @org.springframework.transaction.annotation.Transactional(propagation = Propagation.REQUIRES_NEW) to the method, it also doesn't work.

3 Answers 3

0

there is a few things that come to my mind:

  • you can call EntityManager::flush to flush to the database.
  • set your logging level for org.hibernate.SQL to DEBUG to see what actually is written into the database

Something I avoid totally is sending JPA entities through async methods or through methods that are annotated with REQUIRES_NEW. Let me be clear about this: This may not be the caues of problems. It may be perfectly fine in many situations. But it adds a high level of confusion to your code. Because if you call it

service.someAsyncFunction(customer);
entity.setAge(18);

and

@Async
@Transactional(REQUIRES_NEW)
public someAsyncFunction(Customer customer) {
    cutomer.age++;
    repo.save(customer);
}

then what is the expected outcome?

I took a habit of only passing IDs into methods that are async or annotated with REQUIRES_NEW. And then I load the entity inside this transaction and it will be a different Java Object instance than the one in the outside transaction.

0

I am not sure if I have understood your scenario. But here is my two cents:

  1. Take your saving part repo.save(customer); in a separate method with a new transaction: (propagation = Propagation.REQUIRES_NEW) and
  2. call that method inside sendAllWithQueryParam method.

This should isolate/detach the saving part in a separate transaction to handle this portion. Even if your caller method fails and save call works, the saving part won't be rolledback unlike the other portion.

-2
  • You can use EntityManager to manually flush changes to the database.

  • entityManager.flush();

2
  • flush isn't a commit.
    – M. Deinum
    Commented Jul 2 at 8:21
  • had you checked it? Commented Jul 2 at 13:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.