Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Protecle
- mysql =
- sendFractionalSeconds
- 오블완
- @EntityListeners
- getDateCellValue
- mysql not equal null
- MYSQL
- 버전 문자열 비교
- 운동해서 광명찾자
- EmbeddedId
- yml
- getEntityGraph
- 1*1000
- +9:00
- NamedEntityGraph
- spring boot
- MSSQL
- AuditingEntityListener
- https
- RootGraph
- fractional seconds
- deserializer
- 티스토리챌린지
- @CreateDate
- load order
- mysql equal null
- createEntityGraph
- pooled-lo
- apatch poi
Archives
- Today
- Total
Hello
[spring] 같은 bean에서 Propagation.REQUIRES_NEW 동작하지 않음 본문
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
'spring' 카테고리의 다른 글
[Spring HATEOAS] 유저 정보 관리에 적용해본 내용 정리 (0) | 2024.05.13 |
---|---|
[Spring] RequestParam Enum으로 매핑 (0) | 2024.04.18 |
Spring Data JPA @Modifying (0) | 2023.12.18 |
Jooq(db scan, flyway)로 DB 사용해보기 (0) | 2023.11.17 |
[Spring Boot] Redis Pub/Sub 사용 (0) | 2023.11.09 |