728x90
반응형
≣ 목차
트랜잭션을 잘게 나누면 보정배치가 쉬워지고 트랜잭션이 왜 실패했는지 추적할 수 있다.
충돌 횟수를 고려하여 락 종류를 선택한다.
자기 자신만 접근하는 로직일 경우 충돌이 적을 확률이 높아진다.
트랜잭션 작은 단위로 나눌 시, Manager (application 계층) 추가
또는 service 에서 필요한 repository 를 DI 받아서 하나의 메서드에서 처리한다.
만약 연관 관계가 맺어져있다면?
reservation.getUser().usePoint(amount)
exception 이후에 코드가 실행되지 않는지 체크하고 테스트 할 필요성이 있다.
트랜잭션 사용 논리적 흐름
구분해서 고려할 필요가 있다.
- 실제 비즈니스 기반의 로직
- 시스템 입장에서의 로직
동시성 제어
트랜잭션
공유락, 배타락 = 트랜잭션 동시성 제어 개념
순서대로 원자대로 시작되기 때문에 먼저 공유락을 걸고 배타락을 걸면
공유락을 사용하는 것들이 조회를 끝낼 때까지 수정 모두 불가
- 공유락(읽기): 여러 트랜잭션이 하나의 데이터를 동시에 읽을 수 있는가?
- @Lock(LockModeType.PESSIMISTIC_READ); // 나 쓰는 동안 읽기는 허용 가능
- 배타락(쓰기): 여러 트랜잭션이 하나의 데이터를 동시에 접근하면 안된다.
- @Lock(LockModeType.PESSIMISTIC_READ); //누구도 나 쓰는 동안 오지마.DB낙관락, 비관락 = DB 에서 동시성 제어
- 낙관적 락: 실패 시 트랜잭션 자체가 실패한다.
- 비관적 락: 성공 시 락을 점유하고 있기 때문에 다른 예약을 조회하거나 변경하려면 기다려야 한다.
- 분산락
DB
낙관적 락
- 자기 컬럼 두고 누가 그 사이에 값을 안 바꿨는지만 본다.
- 낙관적 락은 실제로 락을 거는 것이 아니기 때문에 범위가 커져도 영향을 끼치지 않는다.
- 낙관적 락은 업데이트 할 때 충돌(성공 유무)을 알 수 있다.
재시도
- jpa update 쿼리 나가는 시점은
트랜잭션 종료 시점
이다. - lazy loading - 비즈니스 로직(횟수) 같은 경우 -> 서비스 / 알아서 성공해 -> 인프라 에 둔다.
- retry 로직이 비즈니스 로직에서 관심사로 두어야 하는지 고민할 필요가 있다.
- retry try-catch 사용 or @Retryable https://effortguy.tistory.com/487
- 1차 캐싱 초기화 할 필요 없고 transaction 을 한 번 더 넣으면 된다. (낙관적락 조회, update)
비관적 락
- 주로 배타 락과 연관이 있다. (write, read 불가)
- 트랜잭션이 거대한 경우에 비관적 락이 걸려있는 경우 DB 커넥션이 한정적이기 때문에 DB 커넥션을 계속 붙잡고 기다리고 있어서 문제가 된다.
- DB 커넥션을 가지고 있는 모든 로직에 영향을 끼친다.
- 분산 락을 적용하면 해소 가능
분산락
- 특정 id 에 대해서 분산 락을 획득하고 시작한다.
- 버퍼 못 쓰기 때문에 분산 락 걸면 로딩 가능
- 또는 연산이 자주 일어나는 것인데 예민한 것들에 자주 사용된다. (ex. 선착순 쿠폰)
Redis
캐싱의 목적으로 사용된다.
- 라이브러리 사용 가능
- 계속 구현하는 거 - Lettuce
- pub/sub 으로 받는 거 - Redisson
- ) kafka: 비동기, 메시지 큐 처리
동시성 제어 방식 도입
- lock 을 걸어야 하는 로직 선정
- 낙관 / 비관 중 어떤 것을 선정하는 것이 유의미할까?
- 트랜잭션의 범위는 어느 정도로 축소/확장해야 적용할 수 있을까?
- DB Lock 으로 충분히 제어하지 못하는 로직이 있는가? (트래픽이 쏟아졌을 때 못 버티는 이유는?)
직접 적용해보고, 실제 문제점을 파악하는 것 - 분산 Lock 을 적용했을 때 해소 가능한가?
Log
Thread.currentThread().getName() //현재 스레드의 이름을 가져올 수 있다.
비즈니스 로직에 lock 의 영향 범위를 가시적으로 볼 수 있도록 log 를 넣는다.
낙관적 락을 사용할 때 @Transactional 을 사용할 필요가 없을까요?
낙관적 락 version 업데이트 해야하는데 @Transactional 이 없으면 read only 에러 표시
- Transaction: 데이터의 원자성 보장 및 예외 시 롤백 처리
- Lock: 데이터의 일관성 유지
- 트랜잭션의 단위를 업무 단위로 적용: 하나의 Flow 에서 하나의 작은 단위의 작업이 실패했을 때(낙관적 락 실패) 롤백할 것인지 선택 or 보상 트랜잭션 처리하는 영역
- 트랜잭션이 필요하지 않은 경우? 낙관적 락이 실패하든 말든 상관 없는 경우
728x90
반응형
'Back-End > Database' 카테고리의 다른 글
재귀적 CTE(Common Table Expression) (0) | 2024.08.01 |
---|---|
MySQL root 계정 비밀번호 재설정 (0) | 2024.07.09 |
MySQL - Workbench, DB 종류 (0) | 2022.07.19 |
MySQL - 실습문제 (0) | 2022.07.18 |
MySQL - group by, having, join (0) | 2022.07.18 |
댓글