콘텐츠로 이동

2022 11 15

2022-11-15

Thread.currentThread().interrupt()

  • 참고: http://happinessoncode.com/2017/10/09/java-thread-interrupt/
  • Java Thread의 인터럽트 메커니즘
    • 자바에서는 쓰레드에 하던 일을 멈추라는 신호 보내기 위해 인터럽트 사용
    • 한 쓰레드가 다른 쓰레드 인터럽트 가능, 쓰레드 스스로 인터럽트도 가능
    • 각 쓰레드는 자신이 인터럽트 되었는지 확인 가능
  • 인터럽트 확인법
    • Thread.interrupted(): 정적 메서드 -> 호출 후에 interrupt state 사라짐
    • Thread.isInterrupted(): 인스턴스 메서드 -> 호출 후에 interrupt state 유지
  • .interrupt() 왜 필요하냐면
    • 쓰레드를 관리하는 상위 레이어 쓰레드풀에 인터럽트 발생 여부를 알려야함
    • 그래야 적절히 쓰레드풀이 인터럽트를 관리할 수 있음

DB 락

  • 동시성 제어 Lock
    • [Optimistic Lock] => 동시 업데이트 적을 경우
      • 경합이 발생하지 않으리라 봄
      • 재고 하나의 카카오 인형 경합
        • A 트랜잭션
          • READ COUNT = 1개 (VER 150)
          • --업데이트--
          • READ COUNT = 1개 (VER 150)
          • WRITE COUNT = 0개 (반영!)
        • B 트랜잭션
          • READ COUNT = 1개 (VER 150)
          • --업데이트--
          • READ COUNT = 0개 (VER 151)
          • WRITE COUNT = 0개 (충돌! 롤백!)
    • [Pessimistic Lock] => 동시 업데이트 많은 경우
      • 경합이 발생할 가능성이 높다고 봄
      • 다른 사용자는 먼저 레코드 잠금이 릴리즈 될 때 까지 대기!
  • Pessimistic Lock
    • [Shared Lock]
      • read 연산 실행 가능, write 연산 실행 불가능
      • 여러 트랜잭션이 데이터를 읽을 수 있음
    • [Exclusive Lock]
      • read/write 연산 모두 불가능
      • 해당 트랜잭션에서 독점권을 가짐
  • Lock 단위
    • 데이터베이스 - 파일 - 레코드 - 필드
  • 문제점
    • [Blocking]
      • 하나의 트랜잭션이 Exclusive Lock 걸면 무한으로 대기해야 함
      • 하나의 트랜잭션 커밋/롤백 되어야 풀림
    • [DeadLock]
      • 서로다른 트랜잭션이 상대의 트랜잭션으로 인해 걸린 락이 끝나길 대기하는 상태
  • 데드락 해결방안
    1. 트랜잭션 처리 속도 최소화
    2. Lock Timeout을 통한 시간 조절
  • InnoDB의 락
    • transaction의 ACID 원칙과 동시성을 최대한 보장하기 위해 다양한 종류의 Lock 사용
    • [Row-Level Lock] => Select S Lock - 수정 X Lock
      • SELECT 쿼리에 대해 Shared Lock
      • UPDATE/DELETE 쿼리에 대해 Exclusive Lock
      • 규칙
        • 여러 트랜잭션이 동시에 한 row에 S Lock 걸 수 있음 => 동시에 한 row 읽기 가능
        • S Lock 걸린 row에 다른 트랜잭션이 X Lock 걸 수 없음
        • X Lock이 걸린 row에는 S Lock/X Lock 둘 다 못검
    • [Record Lock] => 레코드 인덱스에 락!
      • DB의 index record에 걸리는 락
      • 인덱스 자체에 X Lock을 걸어버림
      • 따라서 레코드 자체에 정합성 보장
    • [Gap Lock] => 레코드 범위에 락!
      • 조건에 해당하는 곳에 새로운 row가 추가되는 것을 방지하기 위함
      • id=13, id=17이 있는 경우
      • SELECT c1 FROM t WHERE id BETWEEN 10 and 20
      • 10과 20 사이에 갭락이 걸리면서 X Lock 발동
    • 락들은 커밋/롤백 시에 언락!
  • Repeatable Read vs Read Committed

    • 현재 테이블에 13, 17 투입됨
    • [Transaction A]
      (1) SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
      (2) SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
      (3) COMMIT;
      
    • [Transaction B]
      (1) INSERT INTO t VALUES (15);
      (2) COMMIT;
      
    • [A, B 순서]
      (A-1) SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
      (B-1) INSERT INTO t VALUES (15);
      (B-2) COMMIT;
      (A-2) SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
      (A-3) COMMIT;
      
    • Read Committed 라면 레코드 락만 걸기때문에...
      • 처음보는 15가 A-2에서 튀어나옴
    • Repeatable Read 라면 갭락을 걸어주니까...
      • 처음보는 놈 안나옴! 기다려라 트랜잭션 B!
  • InnoDB는 Gap Lock을 통해 Repeatable Read의 Phantom Read 문제 해결!