1. 개요
데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위를 뜻한다.
일반적인 컴퓨터 과학에서는 쪼개질 수 없는 업무처리의 단위를 의미하기도 한다.
2. 트랜잭션의 성질
- 원자성 : 한 트랜잭션 내에서 실행한 작업은 하나로 간주한다. 즉 목두 성공 혹은 모두 실패다.
- 일관성 : 트랜잭션은 데이터 인터그리티 만족등 일관성있는 데이터베이스 상태를 유지한다.
- 격리성 : 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않게 격리한다.
- 지속성 : 트랜잭션이 성공적으로 실행되면 결과는 항상 저장된다.
3. 개발에서의 트랜잭션
DB 접근이 발생하는 여러 단위 작업들을 의미있는 그룹으로 묶어서 일괄 커밋 또는 일괄 롤백하는 매커니즘을 뜻한다.
1. 프레임워크들에서는 다음과 같은 기법들을 사용하거나 지원한다.
2. 선언적 트랜잭션 관리 방법 사용
- annotation 방식으로 @Transactional을 선언하여 사용하는 방법이 일반적이며 이를 선언적 트랜잭션이라고 부른다.
3. JDBC
- JDBC, MyBatis등을 사용할 때는 DataSourceTransactionManager를 관리자로 등록한다.
- 이 클래스는 dataSource 프로퍼티를 통해 전달받은 Connection으로 커밋, 롤백을 수행하면서 관리한다.
4. JPA 트랜잭션 방식 지원
- JPA 트랜잭션은 JpaTransactionManager를 Bean으로 등록하여 사용한다.
- 이 클래스는 프로퍼티를 통해 전달받은 EntityManagerFactort를 이용해서 트랜잭션
5. JTA 트랜잭션 방식 지원
- 다중 자원에 접근 시 JTA(Java Transaction API)를 사용하는데, JTA 트랜잭션은 JtaTransactionManager를 Bean으로 등록하여 사용한다.
6. Nested Transaction 지원
7. 복수 DataSource에 대한 트랜잭션 관리 제공
8. Lazy Connection
- Lazy Connection이란 쿼리 호출 시점에 해당 데이터 소스만 연결하는 것이다.
- Lazy Connection 적용 시, 여러 Lazy Bean Id를 리스트로 등록하고 미적용 시 일반적인 데이터소스 Bean Id를 리스트로 등록한다.
9. 타임아웃 속성 지원
- 지정한 시간 내에 해당 메소드 수행이 완료되지 않는다면 롤백을 수행한다. -1 이라면 타임아웃이 없다.
- @Transactional(timeout=10)
4. 선언적 트랜잭션
선언적 트랜잭션 방법은 <tx:advice> 태그를 사용하는 방법과 @Transactional 어노테이션을 사용하는 방법이 있다.
4.1 tx 네임스페이스 사용
Bean 설정 파일에서 tx 네임 스페이스를 추가하여 트랜잭션 속성을 정의한다.
4.2 어노테이션 기반 설정
@Transactional 어노테이션은 메소드나 클라스, 인터페이스에 적용되며 속성 설정이 가능하다. (propagation의 디폴트가 REQUIRED)
@Transactional(propagation=Propagation.REQUIRED)
@Transactional
@Override
public void removeBoard(BoardVO vo) throws Exception {
replyDAO.removeAllRepl(vo.boardNo);
boardDAO.deleteBoard(vo.boardNo);
}
5. Transactional 속성( Propagation - Nested Transaction)
한 트랜잭션 내부에서 중첩된 트랜잭션 처리가 필요할 때 사용하는 기능이다. Spring은 propagation속성을 통해 Nested Transaction을 지정한다.
Propagation(전파옵션)이란?
- REQUIRED : 이미 시작된 트랜잭션(부모 트랜잭션)이 있으면 참여하고 없으면 새로 시작한다. (디폴트)
- SUPPORTS : 이미 시작된 트랜잭션이 있으면 참여하고 없으면 트랜잭션 없이 진행한다.
- REQUIRED_NEW : 부모 트랜잭션을 무시하고 항상 새로운 트랜잭션을 시작한다.
- NESTED : 메인 트랜잭션 내부에 중첩된 트랜잭션을 시작한다. 부모 트랜잭션 결과에는 영향을 받지만, 자신의 트랜잭션 결과는 부모에게 영향을 미치지 않는다.
- NOT_SUPPORTED : 트랜잭션을 사용하지 않게 한다. 이미 진행 중인 트랜잭션이 있으면 보류시킨다.
- MANDATORY : REQUIRED와 비슷하게 이미 시작된 트랜잭션이 있으면 참여하지만, 트랜잭션이 시작된 것이 없으면 예외를 발생시킨다. (혼자서 독립적으로 트랜잭션을 진행하면 안되는 경우에 사용)
- NEVER : 트랜잭션을 사용하지 않게 하며 이미 시작된 트랜잭션이 있으면 예외를 발생시킨다.
이중 프로젝트 수행중에 많이 쓰이는 것은 REQUIRED, REQUIRES_NEW, NESTED, SUPPORTS 이다.
이러한 옵션을 설정하는 방식은 어노테이션 방식과 xml 방식이 있다.
- 어노테이션 방식 : @Transactional(propagation=Propagation.NESTED, rollbackFor=Exception.class)
- xml 방식 : <tx:method name="insert*" propagation="NESTED" rollback-for="Exception" />
6. Transactional 속성(Isolation)
격리 레벨에 대해 알아보자.
- DEFAULT : 기본 설정, 기본 격리 수준
- SERIALIZABLE : 가장 높은 격리, 성능 저하 가능성 있음
- READ_UNCOMMITED : 커밋되지 않은 데이터 읽을 수 있음
- READ_COMMITED : 커밋된 데이터에 대해 읽기 허용
- REPEATABLE_READ : 동일 필드에 대한 다중 접근 시 동일 결과 보장
'Study > 데이터베이스' 카테고리의 다른 글
[DB] Numeric과 Integer의 차이! (0) | 2023.07.04 |
---|---|
Redis란? 레디스의 기본적인 개념 (인메모리 데이터 구조 저장소) (1) | 2023.05.02 |
댓글