DB 트랜잭션
transStart/transComplete, 수동 롤백, 예외 기반 자동 롤백 등 CI4 트랜잭션 패턴을 계좌 이체 시나리오로 학습합니다.
현재 계좌 잔액
초기화홍길동
100,000 원
계좌 #4
김철수
50,000 원
계좌 #5
이영희
200,000 원
계좌 #6
트랜잭션 시나리오 실행
transStart / transComplete
가장 기본적인 트랜잭션 패턴입니다. transStart()와 transComplete() 사이의 모든 쿼리가 하나의 트랜잭션으로 묶입니다. 오류 발생 시 자동으로 롤백됩니다.
$db = db_connect();
$db->transStart();
// 출금
$db->table('accounts')
->where('id', $fromId)
->update(['balance' => $from->balance - $amount]);
// 입금
$db->table('accounts')
->where('id', $toId)
->update(['balance' => $to->balance + $amount]);
$db->transComplete();
// 트랜잭션 성공 여부 확인
if ($db->transStatus() === false) {
// 실패 처리
}
transStatus() —
transComplete() 호출 후 false면 내부 오류로 롤백된 것입니다.
transRollback — 수동 롤백
비즈니스 로직 조건(잔액 부족 등)으로 직접 롤백이 필요할 때 transRollback()을 호출합니다.
$db->transStart();
$from = $db->table('accounts')->where('id', $fromId)->get()->getRowObject();
// 잔액 부족 → 수동 롤백
if ($from->balance < $amount) {
$db->transRollback();
return redirect()->back()->with('error', '잔액이 부족합니다.');
}
$db->table('accounts')->where('id', $fromId)
->update(['balance' => $from->balance - $amount]);
$db->table('accounts')->where('id', $toId)
->update(['balance' => $to->balance + $amount]);
$db->transComplete();
transRollback() 호출 후에는 이후 쿼리가 트랜잭션 밖에서 실행될 수 있으니 즉시 함수를 종료하세요.
try/catch + transRollback — 예외 기반 롤백
외부 서비스 호출이나 예측 불가한 오류를 대비한 패턴입니다. try/catch로 예외를 잡아 명시적으로 롤백합니다.
$db->transStart();
try {
$db->table('accounts')->where('id', $fromId)
->update(['balance' => $from->balance - $amount]);
// 외부 API 호출 등 오류 발생 가능한 작업
externalApiCall(); // RuntimeException 발생
$db->table('accounts')->where('id', $toId)
->update(['balance' => $to->balance + $amount]);
$db->transComplete(); // 정상 완료 시 커밋
} catch (\RuntimeException $e) {
$db->transRollback(); // 예외 발생 시 전체 롤백
log_message('error', '이체 실패: ' . $e->getMessage());
return redirect()->back()->with('error', '처리 중 오류가 발생했습니다.');
}
출금 후 예외 발생 시나리오
출금 쿼리는 실행됐지만 예외 →
출금 쿼리는 실행됐지만 예외 →
transRollback() → 출금도 취소됩니다. DB는 트랜잭션 시작 전 상태로 복원됩니다.