웹 개발이나 데이터베이스 설계에서 가장 중요한 요소 중 하나는 데이터의 신뢰성이다.
특히 여러 개의 INSERT 작업이 한 번에 실행될 때, 도중에 하나라도 실패하면 전체 작업을 롤백해야 하는 상황이 생긴다.
이럴 때 사용하는 기능이 바로 트랜잭션(transaction)이다.
MySQL에서는 START TRANSACTION, COMMIT, ROLLBACK 문을 사용해서 INSERT 문을 안전하게 묶어서 처리할 수 있다.

🔍 트랜잭션이란 무엇인가?
트랜잭션(Transaction)은 하나의 논리적인 작업 단위를 구성하는 일련의 SQL 문장 집합이다.
예를 들어 은행 송금처럼 여러 작업이 모두 성공해야만 최종 적용되어야 하는 경우 트랜잭션이 필요하다.
MySQL에서는 다음과 같은 명령어를 사용해 트랜잭션을 제어한다.
- START TRANSACTION 또는 BEGIN : 트랜잭션 시작
- COMMIT : 트랜잭션 정상 종료 및 적용
- ROLLBACK : 트랜잭션 취소 및 이전 상태로 복원
✅ 트랜잭션과 INSERT 문을 함께 사용하는 기본 구조
START TRANSACTION;
INSERT INTO 테이블명 (컬럼1, 컬럼2) VALUES ('값1', '값2');
INSERT INTO 테이블명 (컬럼1, 컬럼2) VALUES ('값3', '값4');
COMMIT;
이렇게 하면 여러 개의 INSERT 문이 하나의 단위로 묶여 처리되며,
중간에 에러가 발생하면 ROLLBACK을 통해 모든 작업을 취소할 수 있다.
🧪 기본 예제 – 사용자 정보와 포인트 내역 동시 저장
START TRANSACTION;
INSERT INTO users (id, name, email)
VALUES (101, '홍길동', 'hong@example.com');
INSERT INTO points (user_id, amount, reason)
VALUES (101, 1000, '가입 축하 포인트');
COMMIT;
위처럼 두 개의 테이블에 데이터를 동시에 넣어야 할 경우,
중간에 하나라도 실패하면 둘 다 INSERT되지 않도록 트랜잭션을 활용해야 한다.
⚠️ 중간 실패 시 ROLLBACK 예제
START TRANSACTION;
INSERT INTO users (id, name) VALUES (200, '김철수');
-- 외래키 제약조건 실패 등 오류 발생 가정
INSERT INTO points (user_id, amount) VALUES (999, 500);
ROLLBACK;
위 쿼리에서 user_id = 999가 존재하지 않아 오류가 발생하면
앞선 INSERT도 자동으로 취소되며 데이터 일관성을 보장할 수 있다.
🔄 트랜잭션 + INSERT IGNORE 조합
실무에서는 종종 트랜잭션 안에서 중복 데이터를 무시하고 삽입할 필요도 있다.
START TRANSACTION;
INSERT IGNORE INTO logs (ip, action) VALUES ('192.168.0.1', '접속시도');
INSERT IGNORE INTO logs (ip, action) VALUES ('192.168.0.1', '접속시도');
COMMIT;
이런 방식은 로그 테이블, 히스토리 테이블 등에 적합하다.
중복으로 인한 중단을 막으면서도 데이터 무결성은 유지된다.
🧠 트랜잭션 안에서 예외 처리하는 습관 기르기
MySQL 단독으로는 SQL 내 조건 분기나 예외처리를 할 수 없기 때문에,
애플리케이션 레벨에서 try-catch 문으로 에러 발생 시 ROLLBACK을 호출하는 패턴이 일반적이다.
try {
connection.setAutoCommit(false);
// INSERT 1
// INSERT 2
connection.commit();
} catch (Exception e) {
connection.rollback();
}
Spring, Node.js, PHP 등 다양한 백엔드 언어와 함께 사용할 수 있는 패턴이며,
이러한 구조를 통해 서비스의 데이터 안정성이 크게 향상된다.
🔐 주의사항
- 트랜잭션은 InnoDB 스토리지 엔진에서만 동작하며, MyISAM에서는 작동하지 않는다.
- 반드시 COMMIT 또는 ROLLBACK으로 트랜잭션을 종료해야 한다.
- 트랜잭션 중에는 다른 세션이 해당 데이터에 접근하지 못할 수도 있으니, 잠금 상태에 주의해야 한다.
- 너무 오래 열린 트랜잭션은 데드락(deadlock)의 원인이 될 수 있다.
💬 실무 활용 팁 – 주문 처리 시 트랜잭션 묶기
START TRANSACTION;
-- 주문 테이블에 주문 정보 저장
INSERT INTO orders (user_id, product_id, quantity)
VALUES (300, 101, 2);
-- 재고 감소 처리
UPDATE products
SET stock = stock - 2
WHERE product_id = 101 AND stock >= 2;
-- 포인트 사용 내역 삽입
INSERT INTO points (user_id, amount, reason)
VALUES (300, -5000, '주문 사용');
COMMIT;
이 예제처럼 하나라도 실패하면 전체 주문을 취소해야 하는 구조에서
트랜잭션은 반드시 필요하다.
📎 공식 문서 참고
MySQL 트랜잭션 공식 문서
https://dev.mysql.com/doc/refman/8.0/en/commit.html
'DB' 카테고리의 다른 글
| [MySQL] SELECT 기본 조회 방법 완벽 정리 (0) | 2025.06.24 |
|---|---|
| [MySQL] 대량 INSERT 성능 최적화 방법 완벽 정리 (1) | 2025.06.20 |
| [MySQL] REPLACE VS INSERT 차이점 완벽 정리 (0) | 2025.06.20 |
| [MySQL] INSERT + AUTO_INCREMENT 사용법 완벽 가이드 (0) | 2025.06.20 |
| [MySQL] INSERT + SELECT 사용법 완벽 가이드 (0) | 2025.06.20 |
| [MySQL] 있으면 UPDATE, 없으면 INSERT (오라클의 MERGE INTO) (2) | 2025.06.19 |
| [MySQL] INSERT IGNORE 사용법 완벽 가이드(데이터 중복 방지) (0) | 2025.06.19 |
| [MySQL] INSERT INTO ... SET 사용법 완벽 가이드 (1) | 2025.06.19 |