확인과 변경 사이의 틈
재고를 읽어 0보다 크면 줄이는 코드를 두 요청이 동시에 실행한다고 해보자. 둘 다 재고 1을 읽고 성공을 결정하면 최종 값이 -1이 될 수 있어. 버그는 어느 한 줄이 아니라 읽기와 쓰기 사이에 있어.
조건과 변경을 한 문장에
UPDATE products SET inventory = inventory - 1 WHERE id = ? AND inventory > 0는 재고 확인과 차감을 원자적으로 처리해. 갱신 행이 0개면 판매하지 않고, 1개면 성공이야.
복잡한 경우의 두 선택
조건이 SQL 한 문장에 들어가지 않으면 SELECT FOR UPDATE로 잠근 뒤 계산하거나 SERIALIZABLE에서 재시도해. 가능하면 UPDATE ... WHERE id = ? AND condition처럼 조건을 WHERE에 밀어 넣는 방식이 가장 단순해.