회고

20220707 TIL #트랜젝션 에러 @Transactional

paran21 2022. 7. 8. 00:45

어제 퇴근 직전에 새로운 에러를 발견했다.

다행히 오늘 오전에 배포할 때 수정해서 같이 적용하면 될 것 같다고 하셔서, 야근은 하지 않아도 됬다.

 

데이터 업로드 중에 오류가 발생하면 롤백이 되어야 하는데 롤백이 되지 않고 생성된 데이터가 그냥 저장되는 문제였다.

 

이전에는

1) Exception 발생 지점

2) 히스토리 데이터 생성

순서였기 때문에 문제가 발생하지 않았는데(엄밀히 말해서 문제를 인지하지 못한 거라고 하는게 맞는 것 같다.)

 

로직이 수정되면서

1) 히스토리 데이터 생성

2) Exception 발생 지점

으로 순서가 변경되면서 exception 발생 시 롤백이 안되고 1)에서 생성된 데이터가 그대로 저장되었다.

 

이 모든 과정을 하나의 트랜젝션 단위로 묶었어야 했다.

 

또, 이 로직 중간에 delete 메서드가 포함되어 있었는데 여기만 따로 @Transanctional과 @Modifying(clearAutomatically = true)로 설정해두었는데, 여기서 영속성 컨텍스트를 clear한 것도 영향이 있는 것 같다.

이 delete메서드 안에 1)히스토리 데이터 생성이 포함되어 있었는데, 데이터 생성까지 하고 나서 영속성 컨텍스트를 clear하기 때문에 db에 1)데이터가 저장이 되었을 것이다.

(그런데 이것과 상관없이 이 메서드를 사용하는 상위 메서드에서 @Transactional로 트랜젝션을 하나로 묶으면 롤백되지 않을까? 테스트 해봤을 때는 @Modifying 어노테이션과 상관없이 정상 작동하는 것을 확인하였다.)

 


 

틈틈히 리펙토링을 진행하고 있는데, 이 delete메서드 안에 1)히스토리 생성은 하나의 메서드가 2개의 다른 일을 수행하고 있기 때문에 분리할 필요가 있다고 생각해서 새로 추가된 도메인에서는 별도의 메서드로 분리하였다.

이번 에러를 수정하면서 트랜젝션 단위에 대해 다시 생각하게 됬다.

한 메서드가 하는 일이 너무 많으면 트랜젝션 단위를 설정하는 것도 더 복잡해지는 것 같다.

또, 해당 메서드를 재사용하려면 포함된 모든 일을 다 수행해야 하기 때문에 재사용성도 떨어지게 되는 것 같다.

 

사실 해당 부분을 구현하면서 특정 경우에 exception을 던질 생각만 했지 트랜젝션 단위는 생각하지 못한 것 같다.

db가 연결되는 곳에서는 항상 트랜젝션 단위를 어떻게 가져가야 할지도 생각하는 습관이 필요할 것 같다.