모든 글 · 4쪽
전체 글 144편 중 37–48번째 글이다. 최신 글이 앞에 있다.
4쪽 글 목록
144편 중 37–48
낙관적 락이냐 비관적 락이냐, 충돌률이 정한다
낙관적 잠금은 빠르고 비관적 잠금은 안전하다는 말, 둘 다 맞게 들려서 더 헷갈린다. 실제로는 충돌이 얼마나 자주 나느냐에 따라 유불리가 뒤집힌다.
따로 보이던 장애 셋, 범인은 긴 트랜잭션 하나였다
커넥션 부족, 테이블 팽창, 락 경합이 한꺼번에 났다. 셋을 하나씩 따로 조사했는데 알고 보니 원인은 하나였다. 트랜잭션이 길다는 것.
알림은 왔는데 주문이 없다, 아웃박스 패턴
주문을 저장하고 바로 알림 이벤트를 보냈다. 가끔 알림 서비스가 「그런 주문 없는데요」라고 했다. 취소된 주문 알림이 나가기도 했다. 순서를 바꿔도 안 풀린다.
워커를 늘려도 그대로인 DB 큐, SKIP LOCKED 로 푼다
DB 테이블로 만든 작업 큐에 워커를 다섯으로 늘렸다. 처리량은 한 대일 때와 똑같았다. 다섯이 전부 맨 앞 작업 하나 앞에 줄을 서고 있었다.
CPU 도 DB 도 한가한데 앱이 멈췄다, REQUIRES_NEW
로그만은 남기려고 저장 메서드를 별도 트랜잭션으로 뺐다. 그런데 트래픽이 오르자 CPU 도 DB 도 한가한데 앱이 멈췄다. 요청 하나가 커넥션 둘을 쥐고 있었다.
@Transactional 을 붙였는데 롤백이 안 된다
트랜잭션 애너테이션을 붙였는데 예외가 나도 롤백이 안 된다. 오타도 없고 임포트도 맞다. 로그를 켜 보면 트랜잭션이 아예 시작되지 않았다.
쓰기 스큐, 각자는 옳은데 합치면 틀리다
당직은 최소 한 명이 남아야 하는데, 두 사람이 동시에 해제를 눌렀더니 0명이 됐다. 검사도 있었고 트랜잭션도 걸려 있었다. 어디가 틀렸을까?
두 번 적립했는데 포인트가 한 번만 들어갔다
포인트 적립 요청이 두 번 다 성공했는데 잔액에는 한 번만 들어가 있다. 에러가 하나도 없어서, 정산 때가 돼서야 알게 되는 종류의 사고다.
결제사가 느려졌을 뿐인데 우리 서비스가 멈췄다
결제사가 조금 느려졌을 뿐인데 결제와 상관없는 화면까지 우리 서비스가 통째로 멈췄다. 원인은 트랜잭션 안에서 부른 외부 API 였다.
JSON 컬럼은 스키마를 미루는 빚이다
요구사항이 자주 바뀌어 JSON 컬럼에 속성을 몰아넣었더니, 1년 뒤엔 어떤 키가 들어 있는지 아무도 모른다. 조회도 느려졌다. 빨리 가려던 선택에 이자가 붙었다.
대량 적재 뒤에만 느려지는 쿼리, 범인은 낡은 통계
데이터를 왕창 넣은 직후부터 쿼리가 느려졌다가 시간이 지나면 저절로 낫는다. 그래서 원인을 못 찾고, 다음 적재 때 똑같이 또 느려진다.
인덱스가 분명히 있는데 순차 스캔이 뜬다
인덱스를 만들었는데 쿼리는 그대로 느리다. 개발 DB 에선 잘 타던 인덱스를 운영에서만 안 탄다. 그런데 옵티마이저가 인덱스를 안 쓰는 게 옳은 판단일 때가 생각보다 많다.
조건에 맞는 글이 없다. 브루니가 숨었나 보다.