spring
[spring] 같은 bean에서 Propagation.REQUIRES_NEW 동작하지 않음
nari0_0
2024. 1. 29. 17:18
728x90
master, slave 환경의 DB를 사용하고 있어 RoutingDataSource를 구현해 readOnly일 때 slave를 바라볼 수 있도록 사용하고 있습니다.
아래처럼 otherService가 호출 되었을 때, 각각의 트랜잭션으로 동작할 것을 기대했으나 SQL Error: "1290," SQLState: HY000 에러를 만나게 되었습니다.
getOne에서 열린 트랜잭션에 포함되어 save메소드가 동작해 에러가 발생한 것입니다. @Transactional은 AOP 프록시를 생성합니다. 같은 빈에서 @Transactional이 붙은 메소드를 여러개 호출 시 최초 호출 되는 메소드의 옵션으로 프록시가 생성됩니다.
아래를 코드는 readOnly 옵션으로 트랜잭션이 활성 된 후 해당 트랜잭션에 save 메소드 동작이 참여하게 됩니다.
@Service
public class ExampleService {
@Autowired
private SimpleService simpleSevice;
@Autowired
private OtherService otherService;
public void someLogic(Integer id, SimpleRequest form) {
...
Other other = otherService.getOne(id);
...
otherService.save(other);
}
}
@Service
public class OtherService {
@Autowired
private OtherRepo otherRepo;
@Transactional(readOnly = true)
public Other getOne(Integer id){
return otherRepo.findById(id).orElseThrow(() -> new RuntimeException("not found other"));
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Other other) {
simpleRepo.save();
}
}
after
OtherService.save 메소드 내에서 getOne을 호출하도록 로직 수정해 해결했습니다.
불필요해진 propagation 옵션 또한 제거.
@Service
public class ExampleService {
@Autowired
private SimpleService simpleSevice;
@Autowired
private OtherService otherService;
public void someLogic(Integer id, SimpleRequest form) {
...
otherService.save();
}
}
@Service
public class OtherService {
@Autowired
private OtherRepo otherRepo;
@Transactional(readOnly = true)
public Other getOne(Integer id){
return otherRepo.findById(id).orElseThrow(() -> new RuntimeException("not found other"));
}
@Transactional
public void save() {
Other other = getOne(id);
...
simpleRepo.save();
}
}
프록시를 사용해 트랜잭션을 생성해 사용하는 것을 볼 수 있다.
참고 :
728x90