일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 자바
- 오라클 디비
- smart cast
- 파이썬 소스
- resilience4j
- hyperledger
- spring
- gradle
- 운영체제
- oracle
- 자바 프로젝트
- MongoDB
- 리눅스
- 오라클
- jsp
- 유사코드
- 초대장
- dynamic query
- c#
- SQL
- 문법 정리
- 알고리즘
- 파이썬
- JVM
- auto configure
- 백준 알고리즘
- 티스토리
- 프로젝트
- 학점
- K6
- Today
- Total
모종닷컴
스프링 트랜잭션 범위 생각해보기 본문
이전에 회사에서 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 |