일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 스파르타내일배움캠프
- 메서드
- Github_token
- 해우소
- 회고록
- 내일배움캠프
- #스파르타내일배움캠프TIL
- 생성자
- 스레드
- Diary 해우소
- diary
- KPT
- 스파르타내일배움캠프TIL
- Git
- Token
- TiL_1st_0419
- 포맷은 최후의 보루
- Java의 이점
- #스파르타내일배움캠프
- 인스턴스
- #내일배움캠프
- 변수의 다양성
- JVM
- static
- 성장기록
- GitHub
- 감사기록
- 클래스
- Java
- 객체지향 언어
- Today
- Total
몬그로이
동시성 제어 요약 본문
동시성 제어가 안 되는 이유
- Spring AOP 로 인해 프록시 객체가 만들어지고
원래 객체인 service의 transactional 때문
bc2인스턴스
자르파일 빌드해서 배포
서버가 한 대 일때는 ok
여러 대일땐 synchronized 안 먹힘
**@sync~~
자바에서 메서드 위에 적으면 한 개씩만 들어가도록 만들어줌 (또는 class 위에 적음)
단, 서버가 여럿이면 제어 안 됨
여러 서버에서 A 메서드에 동시 접근할 수 있으므로
따라서 이 방법 안 씀
DB락(비관적 락)
DB 레코드에서 직접적으로 Lock 걸어 제어
비관적 락 디폴트는
s-lock 읽기 잠금 @Lock(LockModeType.PESSIMISTIC_READ) in Repository
x-lock 쓰기 잠금 (다른 lock 이 걸려있으면 안 됨)
transactional 과 함께 사용
여러 DB에서는 동시성 제어 불가
낙관적 락
version 컬럼을 추가하여 버전이 다르면 업데이트를 불가능하게 만드는 것
즉, 변경사항이 생기면 버전이 올라가므로 다른 버전으로 확인되어 변경 안 됨
@Version
private int version;
재시도 로직이 필요함 -> 이로 인해 서버 다운 가능
하지만 DB에 직접 락을 걸지 않기 때문에 동시 요청 횟수가 적을 때는 성능 향상에 이점이 있음(즉 충돌이 자주 발생하지 않을 경우 좋음)
비관적 락처럼 @Lock(LockedType.Optimistic_force_increment) 가능하긴 하나
조회, 수정 각각 1씩 오름 ->> 카운트가 2배 따라서 비추
분산락(Ditributed Lock)
임계구역에 Lock 관리 (key 부분에서 관리)
자원에 거는 것이 아니라 행위가 발생하는 곳에 거는 방식으로
Redis 를 활용하는 락임
Mysql 도 가능하지만 Redis 에 비해 성능 떨어짐
Redis 가 가능한 이유
1. MemoryDB
2. 싱글 스레드
Lettuce
SpinLock 사용하므로
spin 돌면서 계속 권한 요청(보챔)하므로 다운 가능
Redisson
한 서버에서만 가지고 있으면 여러 서버에서도 동시성 제어 가능
pub/sub 방식 = Lock 을 가져갈 수 없으면 그냥 대기 (spin 안 함)
lease time 설정 가능
++ Lock 사용하지 않고 redis 싱글 스레드 특성을 이용한 동시성 제어 가능
RedisTemplate
싱글 스레드 특성 이용한 동시성 제어
ops.decrement("counter", "100(재고)"); 을 메서드 블럭에 넣어주면 됨
트랜젝션 직렬화를 Redis 가 수행함
싱글스레드라서 한 명 뿐이므로 아무리 여럿 들어와도 순차적으로 처리함
In-memory 가(?) 굉장히 빠르게 하나씩 100개 수행함
싱글 스레드이므로 getCounter->setCounter 가 한 세트로 움직여버리는 느낌
getCounter 에서 setCounter 로 넘어가는 중에 새로운 getCounter 를 수행하지 않음
=========
1. Synchronized : method 또는 class 위에 선언하면, 단일 쓰레드만 접근하도록 해서
- 한계점: 서버가 여러대면 동시성 제어가 불가능 (쓰레드 30개)
-> A 서버 A Synchronized Method 접근 (단 1개만)
-> B 서버 A Synchronized Method 접근 (단 1개만)
-> C 서버 A Synchronized Method 접근 (단 1개만)
2. DB Lock
1. 비관적 락 (Pessimistic Lock) : Shared Lock(s-lock), Exclusive Lock(x-lock) 기반으로 DB 레코드 직접적으로 잠금을 걸어서 다른 트랜잭션들이 접근하지 못하게 함.
2. 낙관적 락 (Optimistic Lock) : Version 컬럼을 통해 데이터가 수정되었는지 확인 후, 수정되었으면 (Version이 일치하지 않으면) 롤백 및 예외 발생. -> catch 재시도
- 한계점: 락으로 인한 성능 저하, 항상 성립하는 건 아님
3. 분산락
1. Lettuce: Spin Lock -> 락 내놔 계속 보채는거죠 -> Redis 부하가 집중됨.
2. Redisson: pub/sub -> 락을 얻지 못하면 안 보채고 대기. -> Lock을 획득할 수 있는 상태가 되면 (lock.unlock()) Redisson 이 구독자들한테 알려줌 (락 가질사람 ~?)
3. RedisTemplate: Redis 의 싱글 스레드 특성을 활용 -> 동시다발적으로 요청이 들어와도 결국 그 요청을 처리하는 스레드는 1개이기 때문에, 어쩔수 없이 순차적으로 처리함 -> 동시성 제어
'Organizing Docs > Spring Docs' 카테고리의 다른 글
주의가 필요한 일대다 단방향 (0) | 2024.07.19 |
---|---|
MVC 디자인패턴 (0) | 2024.07.18 |
Jpa repository 메서드 명명규칙 - 공식문서 참고 (0) | 2024.07.12 |
QueryDSL (0) | 2024.06.30 |
Entity-Table 에 사용하기 좋은 어노테이션 기능 (0) | 2024.06.30 |