Spring @Transactional: interaction between isolation and propagation of transactions
Asked Answered
S

0

0

This directly relates to this other question, as a natural follow-up question (which was asked in comments, but was never replied to).

Textual description

Assuming:

  • the application uses the default REQUIRED transactional propagation
  • the application uses the DEFAULT transactional isolation
  • the database's transactional isolation defaults to READ_COMMITTED (e.g. Postgres)

Two operations exist in separate classes:

  1. Read some entries
  2. Read some entries + Update them

Now assume that:

  • the second operation calls the first one to fulfill the "Read some entries" part
  • the second operation's method is marked with @Transactional(isolation=Isolation.REPEATABLE_READ)
  • the first operation's class is marked with @Transactional

How does Spring behave in terms of managing transactions when calling the second operation?


Code description

@Service
@Transactional
class Service1 {
  @Autowired MyRepo repo;

  void read(String id) {
    repo.findById(id);
  }
}

@Service
@Transactional
class Service2 {
  @Autowired Service1 readCommittedService;
  @Autowired MyRepo repo;

  @Transactional(isolation=Isolation.REPEATABLE_READ)
  void whatHappensNow(String id) {
    readCommittedService.read(id);
    repo.modifyRow(id);
  }
}

What happens when we call service2.whatHappensNow("foo") ?

Will Spring create a transaction, with REPEATABLE_READ isolation, and use that same isolation level when calling the repository via the service1.read("foo")?

And if a concurrent request is received, but this time it's a direct call to service1.read("foo") : will that transaction have the appropriate READ_COMMITTED isolation level, thus having no chance of failing or being blocked by that other request coming from service2?

Servais answered 27/1, 2022 at 4:18 Comment(3)
It will use the transaction settings of the point where it started so REPEATABLE_READ. Unless you specify a different propagation level it might start a new transaction with a different isolation level. Each started transaction will have its own propagation and isolation level (as those are based on threads for storing the tx state, so each call will be properly set). I wonder why the question?Scenery
@M.Deinum your comment says "it might start a new transaction". That's precisely the ambiguity I'm trying to lift.Servais
It won't start a new transaction unless there is also a REQUIRES_NEW else it won't. fScenery

© 2022 - 2024 — McMap. All rights reserved.