ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot] @Transactional Rollback 관련 트러블슈팅
    Backend/개발 2023. 1. 30. 02:26
    반응형

    사이드프로젝트 게임 저장로직에 문제가 생겨서 해결하다 알게 된 내용을 정리해보려고 한다.

    생각보다 간단하고 많이 봤던 이슈였는데 발견하는데 좀 오래 걸려서 기록 남기기용..

     

    게임을 저장할 때 

    1. 게임 정보 저장
    
    2. 팀 정보 저장
    
    3. 참가자 정보 저장
    
    3-1. 회원 정보 업데이트

    이렇게가 @Transactional로 걸려서 한 트랜잭션에 묶여있는데 3-1. 회원정보 업데이트를 하는 로직에 외부 API (라이엇 API)를 호출하는 부분이 있었다.

    우리는 게임 등록을 보통 새벽 12~1시쯤 하게 되고, 게임마다 10명의 참가자의 정보를 외부 API를 호출해서 가져오고 있었는데 이때 왜인지 timeout이 자주 나서 한동안 게임등록이 자꾸 실패했다.

     

     

    그런데 게임 등록이 모두 실패하는 게 아니고 1,2는 저장되어서 목록에 애매하게 남고 참가자 정보만 저장이 안 돼서 이상한 오류가 나고 있었다.. 

    이론상으로 @Tranactional로 걸었으면 1,2 진행하고 3이 에러가 나면 1,2도 복구되어야 하는데..!!

     

     

    결론은 @Transactional은 기본으로 UnCheckedException(ex. RuntimeException)에 대해서만 rollback처리를 해주고 있다.

    외부 API를 호출하면서 timeout으로 SocketException이 터지는데 SocketException은 I/O Excpetion이라서 rollback이 안된 것이었다! 

     

    By default, a transaction will be rolling back on RuntimeException and Error but not on checked exceptions (business exceptions). 

     

    면접 준비할 때 이런 거 이론적으로 달달 외웠는데 막상 내가 개발할 때 처리를 안 하고 있었네..ㅠ.ㅠ

     

     

     

    여튼 그래서 게임 등록하는 로직에만 rollbackFor 설정을 따로 해주었다.

    다른 블로그 좀 더 찾아보면 CheckException들을 다른 UnCheckedException으로 바꿔서 발생시키거나 try catch 전략을 짜줘야 한다는 것 같다. 이거는 좀 더 찾아보겠다.. (급하게 내용만 쓰느라고 )

     

    그래도 이 경험으로 일어날 수 있는 예외가 CheckedException인 경우인지 (외부 api 호출 등 ) 보고 그럴 때 롤백에 대한 처리가 되었는지 한 번씩 다시 보게 되는 습관이 생긴 것 같다. 

    댓글

Designed by Tistory.