
고급 PHP 프로그래밍 – 데이터베이스 프로그래밍 – 트랜잭션 관리
안녕하세요! 😊
이번 시간에는 데이터베이스에서 데이터의 신뢰성과 안정성을 지키기 위한 핵심 개념인 트랜잭션(Transaction) 관리에 대해 배워보겠습니다.
트랜잭션은 마치 ‘은행 이체’를 떠올리면 이해가 쉬워요.
A 계좌에서 돈을 출금하고 → B 계좌에 입금하는 두 작업이 하나처럼 동시에 성공하거나,
하나라도 실패하면 전체를 되돌리는 것, 바로 그게 트랜잭션이에요!
트랜잭션(Transaction)이란?
트랜잭션은 하나 이상의 데이터베이스 작업을 하나의 논리적인 작업 단위로 묶어서 처리하는 방식입니다.
✅ 트랜잭션의 4대 특성 (ACID)
항목 | 의미 |
---|---|
Atomicity (원자성) | 모두 실행되거나, 모두 실행되지 않아야 함 |
Consistency (일관성) | 작업 전후 데이터의 규칙이 깨지면 안 됨 |
Isolation (격리성) | 동시에 실행되는 트랜잭션은 서로 간섭하면 안 됨 |
Durability (지속성) | 작업이 성공하면 영구 반영되어야 함 |
언제 트랜잭션을 사용할까?
- 은행 이체: A → B 동시에 성공하거나 동시에 실패
- 주문 처리: 재고 감소, 주문 내역 저장, 포인트 차감이 모두 성공해야 함
- 게시글 작성 + 첨부파일 등록 같이 여러 테이블에 동시에 입력되는 작업
PHP에서 트랜잭션 사용하기 (MySQL + mysqli)
✅ 기본 흐름
- 트랜잭션 시작
- 여러 SQL 실행
- 성공하면 커밋(commit)
- 실패하면 롤백(rollback)
1. 트랜잭션 시작: mysqli_autocommit($conn, false)
✅ 예제 1: 성공 시 commit, 실패 시 rollback
$conn = mysqli_connect("localhost", "root", "1234", "test_db");
// 트랜잭션 시작
mysqli_autocommit($conn, false);
$ok = true;
$sql1 = "UPDATE accounts SET balance = balance - 10000 WHERE name = '홍길동'";
$sql2 = "UPDATE accounts SET balance = balance + 10000 WHERE name = '이몽룡'";
if (!mysqli_query($conn, $sql1)) $ok = false;
if (!mysqli_query($conn, $sql2)) $ok = false;
if ($ok) {
mysqli_commit($conn);
echo "✅ 송금 성공!";
} else {
mysqli_rollback($conn);
echo "❌ 송금 실패! 전액 복구됨";
}
// 트랜잭션 자동 모드로 복귀
mysqli_autocommit($conn, true);
2. 객체 지향 방식 (MySQLi 객체)
$conn = new mysqli("localhost", "root", "1234", "test_db");
$conn->autocommit(false); // 트랜잭션 시작
try {
$conn->query("UPDATE products SET stock = stock - 1 WHERE id = 1");
$conn->query("INSERT INTO orders (product_id, quantity) VALUES (1, 1)");
$conn->commit(); // 모든 쿼리 성공 시 반영
echo "🛒 주문 처리 완료!";
} catch (Exception $e) {
$conn->rollback(); // 하나라도 실패하면 모두 취소
echo "❗ 주문 실패: " . $e->getMessage();
}
$conn->autocommit(true);
3. 예외 처리와 트랜잭션 결합
✅ PDO 방식은 try-catch와 궁합이 아주 좋아요!
try {
$pdo = new PDO("mysql:host=localhost;dbname=test_db", "root", "1234");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->beginTransaction();
$pdo->exec("INSERT INTO bank (name, balance) VALUES ('김철수', 50000)");
$pdo->exec("UPDATE total_balance SET total = total + 50000");
$pdo->commit();
echo "✅ 거래 성공!";
} catch (Exception $e) {
$pdo->rollBack();
echo "❌ 거래 실패: " . $e->getMessage();
}
4. 트랜잭션에서 자주 하는 실수
실수 | 설명 |
---|---|
autocommit(true) 안 바꾸기 |
트랜잭션이 끝난 후에는 반드시 다시 켜야 해요 |
부분 성공 후 commit | 중간에 오류가 나면 절대 commit하지 말고 rollback 해야 해요 |
예외 미처리 | try-catch 나 mysqli_error() 로 반드시 오류 체크해야 해요 |
트랜잭션 안 되는 쿼리 사용 | SELECT 만으로는 트랜잭션 효과 없음, InnoDB 엔진 필요 |
5. 트랜잭션이 작동하려면?
- 테이블 엔진이 반드시 InnoDB여야 합니다 (MyISAM은 트랜잭션 불가)
- PHP 설정에서
mysqli_report()
를 통해 오류를 예외로 처리할 수도 있어요:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
트랜잭션 vs 일반 쿼리 비교
항목 | 일반 쿼리 | 트랜잭션 |
---|---|---|
에러 처리 | 개별 쿼리별 처리 | 전체 묶음 처리 가능 |
실패 복구 | 어려움 | 자동 롤백으로 복구 가능 |
보안성 | 낮음 | 높음 |
사용 예시 | 단일 작업 | 여러 쿼리를 묶어서 실행해야 할 때 |
실전 예제: 게시글 + 댓글 + 포인트 저장
$conn = mysqli_connect("localhost", "root", "1234", "board");
mysqli_autocommit($conn, false);
$ok = true;
$ok = $ok && mysqli_query($conn, "INSERT INTO posts (title, content) VALUES ('제목', '내용')");
$ok = $ok && mysqli_query($conn, "INSERT INTO comments (post_id, comment) VALUES (LAST_INSERT_ID(), '첫 댓글')");
$ok = $ok && mysqli_query($conn, "UPDATE users SET point = point + 10 WHERE id = 1");
if ($ok) {
mysqli_commit($conn);
echo "✅ 게시글 작성 완료!";
} else {
mysqli_rollback($conn);
echo "❌ 게시글 등록 실패, 전체 취소됨!";
}
mysqli_autocommit($conn, true);
마무리 요약
항목 | 설명 |
---|---|
트랜잭션 시작 | mysqli_autocommit(false) or $conn->begin_transaction() |
성공 시 | mysqli_commit() or $conn->commit() |
실패 시 | mysqli_rollback() or $conn->rollback() |
적용 대상 | INSERT, UPDATE, DELETE 등 변경 쿼리 |
엔진 조건 | InnoDB 만 트랜잭션 지원 |
예외 처리 | 반드시 try-catch 또는 if (!query()) 검사 필요 |
마무리하며 😊
트랜잭션은 단순히 여러 쿼리를 실행하는 것과는 차원이 다른,
데이터의 일관성과 무결성을 보장하는 안전장치입니다.
앞으로 실제 쇼핑몰, 게시판, 결제 시스템 등을 만들게 된다면
반드시 트랜잭션을 활용해서 신뢰성 있는 프로그램을 만들어야 해요.
다음 시간에는 데이터베이스 마이그레이션과 백업, 관리 전략까지도 이어서 알아보겠습니다!
오늘도 탄탄하게 실력을 쌓아가는 여러분, 멋집니다! 💪📦💻