I have a parent transaction at controller layer, but I want to start a new transaction when I call a repository, to achieve this I tried annotating Repository interface as below
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
public interface EventRepo extends JpaRepository<Event, Integer>{ }
However this seems to not start a new transaction upon calls to EventRepo#save. Why?
Here is my service layer.
public interface IApplicationService {
void save(Event event);
}
@Service
public class ApplicationService implements IApplicationService {
@Autowired
private EventRepo eventRepo;
@Override
public void save(Event event) {
eventRepo.save(event);
}
}
It is in turn called from controller layer
@RequestMapping(value="/{indicator}", method=RequestMethod.POST)
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
@ResponseBody
public String processRequest(@PathVariable Integer indicator) {
Event event = new Event("Student1");
service.save(event);
if(indicator != 0) {
throw new RuntimeException();
}
return "Success";
}
However everything works perfectly if I annotate Service interface with @Transactional
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
public interface IApplicationService {
void save(Event event);
}
When I say working what is mean is, if I run the below curl commands I will see 2 rows in h2 db for Event entity
curl -X POST http://localhost:8080/1
curl -X POST http://localhost:8080/0
I understand it is good to control transactions at Service layer then repository or controller layer, constructing situation this way makes it easy to demonstrate the problem.
Spring boot starter version is 2.5.6 below dependencie have versions managed by springboot starter
- spring-boot-starter-data-jpa
- spring-boot-starter-web
- lombok
- h2
Here is a thread that suggests it should be ok to annotate Repository layer although discourages it. @Transactional on a JpaRepository