Closed ieunji2 closed 2 months ago
머니 충전 - /money/v1/money/charge
case1. (트랜잭션 분리 적용 전)요청 마다 지갑 1의 잔액을 2000원씩 증가시킨다
case2. (트랜잭션 분리 적용 후)요청 마다 지갑 1의 잔액을 2000원씩 증가시킨다
case3. 트랜잭션 로그 살펴보기
2024-03-01T04:05:18.036+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByAccountId]: This method is not transactional.
2024-03-01T04:05:18.036+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByAccountId]: This method is not transactional.
2024-03-01T04:05:18.037+09:00 INFO 4982 --- [io-10000-exec-9] c.h.m.config.redis.DistributedLockAop : 85:LOCK:1 - 1. lock 생성
2024-03-01T04:05:18.037+09:00 INFO 4982 --- [io-10000-exec-9] c.h.m.config.redis.DistributedLockAop : 85:LOCK:1 - 2. lock 획득 시도
2024-03-01T04:05:18.037+09:00 INFO 4982 --- [io-10000-exec-1] c.h.m.config.redis.DistributedLockAop : 77:LOCK:1 - 1. lock 생성
2024-03-01T04:05:18.037+09:00 INFO 4982 --- [io-10000-exec-1] c.h.m.config.redis.DistributedLockAop : 77:LOCK:1 - 2. lock 획득 시도
2024-03-01T04:05:18.038+09:00 INFO 4982 --- [io-10000-exec-9] c.h.m.config.redis.DistributedLockAop : 85:LOCK:1 - 3. lock 획득 성공
2024-03-01T04:05:18.038+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByAccountId]: This method is not transactional.
2024-03-01T04:05:18.038+09:00 INFO 4982 --- [io-10000-exec-9] c.h.m.v.s.MoneyDistributedLockService : 85:614000 - 충전 시작
2024-03-01T04:05:18.038+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.039+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.041+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Getting transaction for [com.hello.money.v1.service.MoneyTransactionService.executeCharge]
2024-03-01T04:05:18.041+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.041+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.041+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.041+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.041+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Completing transaction for [com.hello.money.v1.service.MoneyTransactionService.executeCharge]
2024-03-01T04:05:18.042+09:00 INFO 4982 --- [io-10000-exec-9] c.h.m.v.s.MoneyDistributedLockService : 85:616000 - 충전 완료
2024-03-01T04:05:18.042+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2024-03-01T04:05:18.042+09:00 TRACE 4982 --- [io-10000-exec-9] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2024-03-01T04:05:18.043+09:00 INFO 4982 --- [io-10000-exec-9] c.h.m.config.redis.DistributedLockAop : 85:LOCK:1 - 4. lock 해제 성공
2024-03-01T04:05:18.043+09:00 INFO 4982 --- [io-10000-exec-1] c.h.m.config.redis.DistributedLockAop : 77:LOCK:1 - 3. lock 획득 성공
2024-03-01T04:05:18.043+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByAccountId]: This method is not transactional.
2024-03-01T04:05:18.044+09:00 INFO 4982 --- [io-10000-exec-1] c.h.m.v.s.MoneyDistributedLockService : 77:614000 - 충전 시작
2024-03-01T04:05:18.045+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.046+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.047+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByAccountId]: This method is not transactional.
2024-03-01T04:05:18.047+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [com.hello.money.v1.service.MoneyTransactionService.executeCharge]
2024-03-01T04:05:18.047+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.047+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.047+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.047+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.047+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [com.hello.money.v1.service.MoneyTransactionService.executeCharge]
2024-03-01T04:05:18.047+09:00 INFO 4982 --- [o-10000-exec-10] c.h.m.config.redis.DistributedLockAop : 86:LOCK:1 - 1. lock 생성
2024-03-01T04:05:18.047+09:00 INFO 4982 --- [o-10000-exec-10] c.h.m.config.redis.DistributedLockAop : 86:LOCK:1 - 2. lock 획득 시도
2024-03-01T04:05:18.048+09:00 INFO 4982 --- [io-10000-exec-1] c.h.m.v.s.MoneyDistributedLockService : 77:616000 - 충전 완료
2024-03-01T04:05:18.049+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2024-03-01T04:05:18.049+09:00 TRACE 4982 --- [io-10000-exec-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2024-03-01T04:05:18.049+09:00 INFO 4982 --- [io-10000-exec-1] c.h.m.config.redis.DistributedLockAop : 77:LOCK:1 - 4. lock 해제 성공
2024-03-01T04:05:18.050+09:00 INFO 4982 --- [o-10000-exec-10] c.h.m.config.redis.DistributedLockAop : 86:LOCK:1 - 3. lock 획득 성공
2024-03-01T04:05:18.050+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findByAccountId]: This method is not transactional.
2024-03-01T04:05:18.051+09:00 INFO 4982 --- [o-10000-exec-10] c.h.m.v.s.MoneyDistributedLockService : 86:616000 - 충전 시작
2024-03-01T04:05:18.051+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.052+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.053+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Getting transaction for [com.hello.money.v1.service.MoneyTransactionService.executeCharge]
2024-03-01T04:05:18.053+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.053+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.053+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.053+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-03-01T04:05:18.053+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Completing transaction for [com.hello.money.v1.service.MoneyTransactionService.executeCharge]
2024-03-01T04:05:18.054+09:00 INFO 4982 --- [o-10000-exec-10] c.h.m.v.s.MoneyDistributedLockService : 86:618000 - 충전 완료
2024-03-01T04:05:18.054+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2024-03-01T04:05:18.054+09:00 TRACE 4982 --- [o-10000-exec-10] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
2024-03-01T04:05:18.055+09:00 INFO 4982 --- [o-10000-exec-10] c.h.m.config.redis.DistributedLockAop : 86:LOCK:1 - 4. lock 해제 성공
85번, 77번 동시에 들어옴
77 - findByAccountId 지갑 조회
85 - findByAccountId 지갑 조회
85 - 1. lock 생성
85 - 2. lock 획득 시도
77 - 1. lock 생성
77 - 2. lock 획득 시도
85 - 3. lock 획득 성공
85 - findByAccountId 지갑조회
85 - 충전 시작 - 614000
85 - 충전 완료 - 616000
85 - 4. lock 해제 성공
77 - 3. lock 획득성공
77 - findByAccountId 지갑조회
77 - 충전 시작 - 614000
86 - findByAccountId 지갑조회
86 - 1. lock 생성
86 - 2. lock 획득 시도
77 - 충전 완료 - 616000
77 - 4. lock 해제 성공
86 - 3. lock 획득 성공
86 - findByAccountId 지갑조회
86 - 충전 시작 - 616000
86 - 충전 완료 - 618000
86 - 4. lock 해제 성공
=> 락의 키로 walletId
를 사용하기 위해 MoneyServiceImpl.java
에서 findByAccountId()
로 지갑 조회를 먼저 한 번 하는데, 락 획득 이후에 잔액을 가져오기 위해 다시 지갑 조회를 하면 다른 스레드에서 DB에 커밋한 값이 아닌 기존에 조회한 값을 가져오는 것으로 보임
머니 송금 - /money/v1/money/send
case1. 사용자 A는 요청 마다 지갑1의 머니를 지갑2로 200원씩 보낸다, 사용자 B는 요청 마다 지갑2의 머니를 지갑1로 100원씩 보낸다
84번과 93번 스레드가 경쟁 상태이다
=> 84번[LOCK:2, LOCK:1]
과 93번[LOCK:1, LOCK:2]
이 RedissonMultilock
의 tryLock()
으로 동시에 락 획득을 시도하는데 교착 상태가 발생한 것으로 보인다
오류 내용
머니 서비스 대상으로 부하 테스트 중 발생한 오류입니다. 크게 2가지 오류로 보입니다.
1. 락 해제 시 오류
2. 데이터베이스 커넥션 획득 실패 오류
부하 테스트
부하 테스트 도구로 locust를 사용했습니다.
locust 실행
테스트 결과