
파티션을 4개를 뒀을때는 TPS가 36.4/sec이 나온반면 파티션이 1개일경우엔 18.2/sec이 나왔다. 성능개선이 2배되었다.
테스트
Kafka는 기본적으로 같은 key는 같은 Partition에 들어감
→ 그러니 senderUserId를 key로 설정해 메시지를 Kafka에 보낼 때 지정해줘:
이렇게 하면:
테스트
락 순서 고정 (0) | 2025.04.06 |
---|---|
비관적 락(Pessimistic Lock) 도입 (0) | 2025.04.05 |
포인트 송금 시스템에서의 동시성 처리 및 데드락 이슈 (0) | 2025.04.05 |
RabbitMQ 기반 비동기 아키텍처 도입 성능 개선 사례 (0) | 2025.04.02 |
캐싱을 통한 성능 개선 (0) | 2025.04.01 |
서로 다른 유저 간 교차 송금(A→B, B→A)이 동시에 발생할 경우,
각 쓰레드가 락을 거는 순서가 엇갈리면 데드락이 발생할 수 있어.
예시
- 쓰레드 1: A → B 송금 → A 계좌 락 → B 계좌 락
- 쓰레드 2: B → A 송금 → B 계좌 락 → A 계좌 락
→ 서로 락을 점유한 상태에서 상대 락을 기다리다가 영원히 대기 = 💥 데드락 발생
그래서 우리는 항상 락을 거는 순서를 고정했어.
userId가 낮은 계좌 → 높은 계좌 순으로 락을 획득하도록 해서
락 순서가 일관되도록 보장했어.
이렇게 락 순서를 고정하면,
교차 송금이 발생하더라도 쓰레드들이 항상 동일한 순서로 락을 잡기 때문에
데드락 없이 안전하게 처리할 수 있어.
항목 | Before | After |
락 획득 순서 | 쓰레드마다 달라 데드락 가능성 있음 | 항상 고정된 순서로 락 획득 |
데드락 발생 가능성 | 높음 | 제로 |
교차 송금 안정성 | 불안정 | 안전하게 처리됨 |
kafka를 통한 대규모트래픽 및 동시성 제어 (0) | 2025.04.06 |
---|---|
비관적 락(Pessimistic Lock) 도입 (0) | 2025.04.05 |
포인트 송금 시스템에서의 동시성 처리 및 데드락 이슈 (0) | 2025.04.05 |
RabbitMQ 기반 비동기 아키텍처 도입 성능 개선 사례 (0) | 2025.04.02 |
캐싱을 통한 성능 개선 (0) | 2025.04.01 |
비관적 락 도입
항목 | Before | After |
데이터 정합성 | 충돌 및 데드락 발생 | 안정적 처리 |
에러 발생률 | Deadlock, NoSuchElementException | 없음 |
동시성 처리 전략 | 미비 | 명시적 비관적 락 도입 |
kafka를 통한 대규모트래픽 및 동시성 제어 (0) | 2025.04.06 |
---|---|
락 순서 고정 (0) | 2025.04.06 |
포인트 송금 시스템에서의 동시성 처리 및 데드락 이슈 (0) | 2025.04.05 |
RabbitMQ 기반 비동기 아키텍처 도입 성능 개선 사례 (0) | 2025.04.02 |
캐싱을 통한 성능 개선 (0) | 2025.04.01 |
2025-04-05T16:38:42.166+09:00 WARN 15836 --- [point-service] [pool-2-thread-9] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.166+09:00 WARN 15836 --- [point-service] [pool-2-thread-5] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.166+09:00 ERROR 15836 --- [point-service] [pool-2-thread-9] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
2025-04-05T16:38:42.166+09:00 ERROR 15836 --- [point-service] [pool-2-thread-5] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
2025-04-05T16:38:42.166+09:00 WARN 15836 --- [point-service] [pool-2-thread-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.167+09:00 WARN 15836 --- [point-service] [pool-2-thread-7] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.166+09:00 WARN 15836 --- [point-service] [pool-2-thread-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.166+09:00 WARN 15836 --- [point-service] [pool-2-thread-6] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.167+09:00 ERROR 15836 --- [point-service] [pool-2-thread-3] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
2025-04-05T16:38:42.166+09:00 WARN 15836 --- [point-service] [ool-2-thread-10] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.167+09:00 ERROR 15836 --- [point-service] [ool-2-thread-10] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
2025-04-05T16:38:42.166+09:00 WARN 15836 --- [point-service] [pool-2-thread-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.167+09:00 ERROR 15836 --- [point-service] [pool-2-thread-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
2025-04-05T16:38:42.166+09:00 WARN 15836 --- [point-service] [pool-2-thread-8] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001
2025-04-05T16:38:42.168+09:00 ERROR 15836 --- [point-service] [pool-2-thread-8] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
2025-04-05T16:38:42.167+09:00 ERROR 15836 --- [point-service] [pool-2-thread-7] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
2025-04-05T16:38:42.167+09:00 ERROR 15836 --- [point-service] [pool-2-thread-4] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
2025-04-05T16:38:42.167+09:00 ERROR 15836 --- [point-service] [pool-2-thread-6] o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transaction
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
에러 발생: could not execute statement [Deadlock found when trying to get lock; try restarting transaction] [update point_accounts set total_points=?,user_id=? where account_id=?]; SQL [update point_accounts set total_points=?,user_id=? where account_id=?]
Sender 잔액: 950
Receiver 잔액: 50
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
2025-04-05T16:38:42.229+09:00 INFO 15836 --- [point-service] [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2025-04-05T16:38:42.232+09:00 INFO 15836 --- [point-service] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2025-04-05T16:38:42.306+09:00 INFO 15836 --- [point-service] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
> Task :test
BUILD SUCCESSFUL in 6s
4 actionable tasks: 1 executed, 3 up-to-date
오후 4:38:42: Execution finished ':test --tests "com.timebank.pointservice.service.PointServiceTest.동시성_테스트_송금_충돌"'.
💡 어떤 상황에 유리해?
💪 장점:
⚠️ 주의점:
💡 어떤 상황에 유리해?
💪 장점:
⚠️ 주의점:
💡 어떤 상황에 유리해?
💪 장점:
락 순서 고정 (0) | 2025.04.06 |
---|---|
비관적 락(Pessimistic Lock) 도입 (0) | 2025.04.05 |
RabbitMQ 기반 비동기 아키텍처 도입 성능 개선 사례 (0) | 2025.04.02 |
캐싱을 통한 성능 개선 (0) | 2025.04.01 |
QueryDSL을 활용한 동적 쿼리 최적화 (0) | 2025.03.31 |