
이번 실습에서는 Spring Boot + MyBatis 환경에서 Transaction을 적용해보았다.
단순히 데이터를 insert 하는 것이 아니라, 여러 작업을 하나의 논리적인 작업으로 처리해야 하는 상황에서 왜 Transaction이 필요한지 직접 확인할 수 있었다.
Transaction(Transaction)이란?
트랜잭션(Transaction)은 여러 SQL 작업을 하나의 작업 단위로 묶는 것이다.
예를 들어:
1. 카드 결제 처리
2. 티켓 수량 저장
3. 결제 내역 저장
위 작업들은 서로 연결되어 있기 때문에 일부만 성공하면 안 된다.
만약:
- 카드 결제는 완료
- 티켓 저장은 실패
상황이 발생하면 데이터 정합성이 깨진다.
이러한 문제를 방지하기 위해 사용하는 것이 Transaction이다.
Spring에서의 Transaction 처리
Spring에서는 보통 Service 계층에:
@Transactional
어노테이션을 사용한다.
예시:
@Transactional
public void buyTicket(CardDTO cardDTO, TicketDTO ticketDTO) {
cardDAO.insert(cardDTO);
ticketDAO.insert(ticketDTO);
}
위 코드에서 두 작업은 하나의 Transaction으로 묶인다.
즉:
- 둘 다 성공 → commit
- 하나라도 실패 → rollback
처리된다.
이번 실습에서 적용한 제약조건
이번 예제에서는 ticket 테이블에 check constraint를 설정하였다.
CREATE TABLE ticket (
consumId varchar(10) DEFAULT NULL,
countnum int DEFAULT NULL,
CONSTRAINT ticket_chk_1 CHECK (countnum < 5)
)
즉:
countnum 값은 5 미만만 허용
되도록 제한한 것이다.
Transaction rollback 테스트
카드 결제와 티켓 insert를 동시에 수행한 뒤 티켓 수량을 5로 입력하였다.
그 결과 아래와 같은 오류가 발생하였다.
SQL: insert into ticket(consumId, countnum) values(?,?)
Cause:
java.sql.SQLException:
Check constraint 'ticket_chk_1' is violated.
이는 DB의 제약조건(check constraint)에 의해 insert가 실패한 것이다.
중요한 점 : 카드 결제도 함께 rollback
이번 테스트에서 가장 중요한 부분은:
ticket insert 실패
→ transaction rollback
→ card insert도 취소
되었다는 점이다.
즉:
카드 데이터는 insert 되었지만
티켓 insert 실패로 인해
전체 작업이 rollback 되었다.
이것이 바로 Transaction의 핵심 역할이다.
Transaction이 없다면?
만약 Transaction이 적용되지 않았다면:
card insert 성공
ticket insert 실패
상황이 발생하게 된다.
그 결과:
- 카드 결제 데이터는 저장됨
- 티켓 데이터는 없음
이라는 비정상 상태가 된다.
실제 서비스에서는 매우 위험한 상황이다.
왜 Service 계층에서 Transaction을 사용할까?
보통 Transaction은 Service 계층에서 처리한다.
구조는 일반적으로 아래와 같다.
Controller
↓
Service
↓
DAO
Service 계층은 여러 DAO 작업을 하나의 업무 단위로 처리하는 역할을 한다.
예를 들어:
회원가입
주문 처리
결제 처리
재고 감소
포인트 적립
같은 작업들은 대부분 여러 테이블을 동시에 수정한다.
따라서 Service 계층에서 Transaction을 관리하는 것이 적절하다.
실습을 통해 느낀 점
이번 실습을 통해:
- Spring의 @Transactional 동작 방식
- rollback 처리
- 데이터 정합성 유지
- Service 계층 역할
- DB 제약조건(check constraint)
등을 실제로 확인할 수 있었다.
특히 DB 오류가 발생했을 때 이전 작업까지 자동으로 rollback 되는 부분을 직접 확인하면서 Transaction의 중요성을 이해할 수 있었다.
단순 insert 예제보다 실제 서비스 흐름에 가까운 구조를 경험할 수 있었던 실습이었다.
'Spring' 카테고리의 다른 글
| [Spring Boot] MyBatis 게시판 구현 중 오류 해결 (0) | 2026.05.12 |
|---|---|
| [Spring Boot] @RequestBody와 @ModelAttribute 차이 (0) | 2026.05.11 |
| [Spring Boot] Maven ClassNotFoundException 오류 해결 (0) | 2026.05.11 |