트랜잭션(Transaction)이란?
트랜잭션은 데이터베이스의 일관성과 무결성을 유지하기 위해 여러 SQL 작업을 하나의 단위로 묶어 처리하는 기능입니다.
트랜잭션은 아래 4가지 특징을 보장하며 데이터의 신뢰성을 높입니다.
특징 | 설명 |
원자성 | 트랜잭션 내의 모든 작업이 완전히 수행되거나 전혀 수행되지 않음 |
일관성 | 트랜잭션 완료 후 데이터베이스가 항상 일관된 상태를 유지 |
격리성 | 동시에 실행되는 트랜잭션이 서로 영향을 미치지 않음 |
지속성 | 트랜잭션이 완료되면 변경 사항이 영구적으로 저장됨 |
트랜잭션 명령어
트랜잭션은 START TRANSACTION, COMMIT, ROLLBACK 명령어로 제어합니다.
명령어 | 설명 |
START TRANSACTION | 트랜잭션 시작 |
COMMIT | 모든 작업을 영구적으로 저장 |
ROLLBACK | 작업 취소 및 이전 상태로 되돌림 |
MySQL은 기본적으로 자동 커밋 모드가 활성화되어 있습니다. 트랜잭션으로 작업을 묶으려면 명시적으로 **START TRANSACTION**을 사용해야 합니다.
MySQL에서 트랜잭션 사용하기
아래는 MySQL 콘솔에서 트랜잭션을 사용하는 예시입니다.
트랜잭션 실행 예시
- 트랜잭션 시작
START TRANSACTION;
- 데이터 수정
UPDATE accounts SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET balance = balance + 100 WHERE id = 2;
- 변경 사항 저장 (COMMIT)
- 변경 취소 (ROLLBACK)
트랜잭션 사용 전후 결과
- 트랜잭션 사용 전: 명령 하나가 실패해도 다른 작업은 반영됨.
- 트랜잭션 사용 후: 모든 작업이 성공하거나 실패 시 모두 취소됨.
Express.js에서 트랜잭션 적용하기
Express.js에서 MySQL과 트랜잭션을 활용하려면 mysql2 라이브러리를 사용합니다. 아래는 사용자 탈퇴 시 트랜잭션을 적용하는 예제입니다.



1. 기존 코드 (트랜잭션 미적용)
exports.deleteUser = async (user_id) => {
try {
await pool.promise().query(`DELETE FROM innodb.users WHERE user_id = ?`, [user_id]);
await pool.promise().query(`DELETE FROM innodb.boards WHERE user_id = ?`, [user_id]);
await pool.promise().query(`DELETE FROM innodb.comments WHERE user_id = ?`, [user_id]);
} catch (error) {
console.error('Error deleting user:', error);
return false;
}
};
2. 개선된 코드 (트랜잭션 적용)
exports.deleteUser = async (user_id) => {
const connection = await pool.promise().getConnection();
try {
// NOTE : 트랜잭션 시작
await connection.beginTransaction();
// NOTE : 사용자 삭제
await connection.query(`DELETE FROM innodb.users WHERE user_id = ?`, [user_id]);
// NOTE : 게시글 삭제
await connection.query(`DELETE FROM innodb.boards WHERE user_id = ?`, [user_id]);
// NOTE : 댓글 삭제 (의도적 에러 발생)
throw new Error('Intentional error for rollback test');
// NOTE : 트랜잭션 커밋
await connection.commit();
return true;
} catch (error) {
// NOTE : 롤백
await connection.rollback();
console.error('Transaction rolled back due to error:', error);
return false;
} finally {
// NOTE : 연결 반환
connection.release();
}
};
주요 변경점
- 트랜잭션 시작 및 종료:
- beginTransaction(): 트랜잭션 시작.
- commit(): 모든 작업 성공 시 저장.
- rollback(): 에러 발생 시 모든 작업 취소.
- 에러 핸들링:
- try...catch를 사용해 오류를 탐지하고 적절히 처리.
- 에러 발생 시 rollback() 호출.
- 연결 반환:
- finally 블록에서 connection.release()로 연결을 반환해 리소스 누수 방지.
테스트
- 성공 케이스:
- user_id에 해당하는 데이터가 모두 정상 삭제되고 커밋됩니다.
- 실패 케이스:
- 의도적으로 에러를 발생시켜 롤백이 제대로 작동하는지 확인합니다.
트랜잭션을 사용하면 데이터베이스의 무결성과 안정성을 유지할 수 있습니다. 여러 테이블에서 데이터를 삭제하거나 수정하는 작업에서 트랜잭션을 사용하면 유용할 것 같습니다. 실무에서는 정말 수많은 테이블이 존재해서 트랜잭션을 사용하는 경우가 많습니다. 문제 없이 데이터 처리가 가능하면 좋겠지만, 에러는 언제 어디서 발생할지 모르기 때문에 트랜잭션에 대해서 잘 알아두면 좋습니다. 😉
'카카오 부트캠프 > 내용 정리' 카테고리의 다른 글
AWS EC2 중지 후 재시작, DB 연결이 갑자기 안 되는 이유 (0) | 2024.11.26 |
---|---|
AWS EC2 외부 접속 문제 해결기: 결국 문제는 와이파이였다 (0) | 2024.11.25 |
GIT README.md 작성법: 기본 구조 (1) | 2024.11.21 |
서브쿼리에 대한 정의와 장단점 (2) | 2024.11.20 |
Cross-Origin-Resource-Policy: same-origin 에러 (0) | 2024.11.19 |