모종닷컴

스프링 트랜잭션 범위 생각해보기 본문

생각정리

스프링 트랜잭션 범위 생각해보기

모종 2022. 7. 26. 21:12
반응형

이전에 회사에서 RPS(Request Per Second) 올리기 위한 작업을 한 적이 있었는데 이때 트랜잭션이 중요한 해결점이 되었던 게 생각나서 정리할 겸 글을 써본다.

스프링 트랜잭션 정말 좋긴 한데..

트랜잭션 음.. 좋다! 트랜잭션 안에서 실행되는 일련의 작업들을 하나의 작업으로 보장되고 실패 시 롤백도 할 수 있으니 좋다. 트랜잭션이 없었다면 오류 발생 시 이전 작업을 되돌리는 것도 개발자의 몫이었겠지..?

각설하고 이 좋은 트랜잭션이 부하 테스트에서는 아주 나쁜 놈(?) 이었다. 자세히는 설명할 수 없지만 API 중  3~7초 정도 시간이 소요되는 API가 있다. 트랜잭션 좋으니 당연히 주요 로직에 트랜잭션을 붙였는데 부하 테스트를 하다 보니 Connection 타임아웃 에러가 보였다. 무엇인고 하니 스프링 트랜잭션이 열리면 DB 커넥션 하나를 쭉 가지고 있게 되는데 이 커넥션은 트랜잭션이 종료되기 전까지 반환을 하지 않는다. 예를 들어 데이터베이스 커넥션 풀이 200개라고 가정하고 초당 200개의 요청을 보내게 되면 최초 200개의 요청이 끝나기 전까지 그 이후의 요청은 모두 커넥션을 받기 위해 대기를 타게 된다. 그리고 이 커넥션을 받기 위해 대기하는 시간이 우리가 설정한 시간을 지나게 되면 바로 커넥션 타임아웃 에러가 나는 것이다. 

어떻게 해결해야 할까

고민 고민

해결하는 방법이 여러 가지 있을 수 있겠지만 커넥션 풀을 마냥 늘리기도, 대기 시간을 늘리기도 본질적인 해결 방법이 되지는 않을 것 같다는 생각이 들었고 트랜잭션 범위를 최대한 짧게 짧게 가지도록 하였다. 예를 들면 작업이 A,B,C,D,E,F 등이 있다고 했을 때 (A, B)는 반드시 하나의 작업으로 보장되어야 해서 이때는 트랜잭션 안에서 해결하고 C, D는 트랜잭션이 없어도 되는 작업들이라 트랜잭션을 벗어나서 실행하는 등 트랜잭션의 범위를 짧게 가져갔다. 

고려해보자

이렇게까지 하는 건 좀.. 그렇지 않나?

하지만 모든 API를 이런식으로 매번 짧게 가져갈 필요는 없었다. 위 API는 실제 유저가 사용하는 API라서 이런 식으로 트랜잭션을 짧게 가져갔고, 어드민 API 등은 충분히 예상 가능한 요청 범위이기 때문에 이런 곳은 또 트랜잭션을 크게 잡아놓기도 하였다. 그래서 마냥 짧게 가져가야 한다는 생각은 하지 않아도 될 것 같다. 단! 유저가 사용하는 API라면 꼭 이 점을 고려해보도록 하자.

반응형

'생각정리' 카테고리의 다른 글

D.D.C'23 - Dev Day  (0) 2023.01.29
2022년도 개인 회고  (0) 2023.01.01
코딩 설계가 너무 어려워요  (0) 2022.08.21
실수하면 뭐 어떻습니까?  (2) 2022.07.18