Til
title: 2025-11-06 author: 강병호 date: 2025-11-06 category: TIL/강병호/2025/11 (파일 경로 : TIL/{이름}/{연}/{월}) layout: post (자유) —
트랜잭션을 사용해 본 경험이 있나요? 어떤 경우에 사용할 수 있나요?
-
대답
트랜잭션은 하나의 논리적 작업 단위를 보장하기 위함으로 주로 로직 적으로 “모아니면 도” 처럼 하나로 묶어 처리할 필요가 있을 때 사용합니다. 메가 커피의 쿠폰을 사용할 때가 블록체인에서 스마트 컨트랙트를 실행하는 경우를 예시로
예를 들어, 메가 커피 앱에서 쿠폰을 사용하는 과정에서도 이러한 트랜잭션의 기능이 앱 내에서 사용될 수 있다. 사용자가 아메리카노 무료 쿠폰을 선택하고 결제를 진행할 때, 쿠폰 사용 처리와 결제 확정은 반드시 함께 성공하거나 함께 실패해야한다. 여기서 결제가 실패했는데 쿠폰이 사용처리 된다면 사용자는 손해를 보고 앱의 리뷰는 1점이 찍히는 비즈니스적인 가치를 떨구게 되는 일이 발생하게 된다.
그렇기에 예약과 결제 확정 시 쿠폰이 잘 사용되는 과정이 하나의 트랜잭션 단위에서 함께 처리, 함께 실패되도록 처리 해서 일관된 상태를 유지해야한다.
이러한 방향으로 여러 단계의 로직이 연결된 상태애서 하나의 작업으로 묶어서 데이터의 무결성, 일관성을 보장하기 위해 사용한다.
BEGIN; -- 예약 유효성 재검증 + 잠금 SELECT status, reserved_until, reserved_order_id FROM coupon WHERE id=:coupon_id AND user_id=:uid FOR UPDATE; -- 아메리카노 포함 검증(존재해야 진행) SELECT 1 FROM order_items WHERE order_id=:order_id AND name LIKE '아메리카노%' LIMIT 1; -- 할인 반영(최대 2,000원) UPDATE orders SET discount_amount = LEAST(discount_amount + 2000, 2000), total_amount = GREATEST(total_amount - 2000, 0) WHERE id=:order_id AND user_id=:uid; -- 쿠폰 소비 마킹 UPDATE coupon SET status='CONSUMED', consumed_order_id=:order_id, reserved_until=NULL WHERE id=:coupon_id AND user_id=:uid AND status='RESERVED' AND reserved_order_id=:temp_order_id AND NOW() <= reserved_until; -- 주문 확정 UPDATE orders SET status='PAID' WHERE id=:order_id AND user_id=:uid; COMMIT; -- 중간 실패 시 전부 ROLLBACK