홈 › 대용량·배치 › 07 / 8

락과 데드락

잠금 대기, 데드락 원인과 예방, 잠금 조회
섹션 6진행 0 / 8

5. 자주 하는 실수 (Tip)

실수 1: 트랜잭션 안에서 사용자 입력을 기다린다

화면에서 조회하고 FOR UPDATE 로 잠근 뒤 사용자가 값을 입력하기를 기다리면, 자리를 비운 동안 잠금이 유지됩니다. 다른 사용자의 같은 행 수정이 전부 멈춥니다. 입력은 트랜잭션 밖에서 받고, 저장할 때 짧게 잠급니다.

실수 2: 잠그는 순서가 문장마다 다르다

이체처럼 두 행을 바꿀 때 보내는 쪽 먼저, 받는 쪽 먼저가 섞여 있으면 데드락이 납니다. 여러 행이나 표는 항상 같은 순서(예: id 오름차순, 부모 표 다음 자식 표)로 잠급니다. 코드 리뷰에서 순서를 확인합니다.

실수 3: 데드락 오류를 잡지 않고 사용자에게 노출한다

데드락은 정상 동작이라 몇 번에 한 번은 반드시 납니다. 오류 번호(ORA-00060, MySQL 1213, MSSQL 1205)를 잡아 롤백하고 트랜잭션 전체를 몇 번 다시 시도하는 코드가 없으면 그대로 실패합니다. Oracle 은 트랜잭션이 남으니 반드시 롤백을 호출합니다.

실수 4: 조건에 인덱스가 없다

인덱스 없는 조건으로 UPDATE 나 SELECT ... FOR UPDATE 를 하면 훑은 행이 넓게 잠깁니다(MySQL 은 훑은 행 전부). 서로 다른 행을 고치는 세션끼리도 부딪혀 대기와 데드락이 늘어납니다. 조건 컬럼과 외래 키 컬럼에 인덱스를 둡니다.

실수 5: 한 트랜잭션에서 너무 많은 행을 바꾼다

수백만 건을 한 번에 UPDATE 하면 잠금을 오래 쥐고 다른 세션이 줄줄이 기다립니다. MSSQL 은 약 5,000 개 잠금에서 표 잠금으로 에스컬레이션하기도 합니다. 대용량 06 대량 처리에서 배운 대로 나눠서 커밋합니다.