본문 바로가기

개발/Spring

스프링 트랜잭션(Transaction)

728x90
반응형
트랜잭션

 

트랜잭션(Transaction)은 여러 개의 DML 명령문을 하나의 논리적인 작업 단위로 묵어서 관리하는 것으로, All 또는 Nothing 방식으로 작업 단위가 처리됩니다.
SQL 명령문들이 모두 정상적으로 처리되었다면 모든 작업의 결과를 데이터베이스에 영구 반영(commit) 하지만 그중에 하나라도 잘못된 것이 있으면 모두 취소(rollback) 합니다.

스프링은 트랜잭션 기능을 마이바티스 기능과 연동해서 사용합니다.
트랜잭션 기능은 XML 파일에서 설정하는 방법과 애너테이션을 이용하는 방법이 있습니다.
XML 로 설정하는 방법은 설정 파일이 복잡해지면 불편하므로 현재는 애너테이션으로 트랜잭션을 적용하는 방법을 더 선호합니다.

 

[ 트랜잭션 속성 ]

 

속성 기능
propagaion 트랜잭션 전파 규칙 설정
isolation 트랜잭션 격리 레벨 설정
readOnly 읽기 전용 여부 설정
rollbackFor 트랜잭션을 롤백할 예외 타입 설정
norollbackFor 트랜잭션을 롤백하지 않을 예외타입 설정
timeout 트랜잭션 타임아웃 시간 설정

 

 

[ propagation 속성이 가지는 값 ]

 

기능
REQUIRED 트랜잭션 필요, 진행 중인 트랜잭션이 있는 경우 해당 트랜잭션 사용
트랜잭션이 없으면 새로운 트랜잭션 생성, 기본값으로 설정
MANDATORY 트랜잭션 필요
진행 중인 트래잭션이 없는 경우 에러 발생
REQUIRED_NEW 항상 새로운 트랜잭션 생성
진행 중인 트랜잭션이 있는 경우 기존 트랜잭션을 일시 중지시킨 후 새로운 트랜잭션 시작
새로 시작된 트랜잭션이 종료되면 기존 트랜잭션 계속 진행
SUPPORTS 트랜잭션 필요 없음
진행 중인 트랜잭션이 있는 경우 해당 트랜잭션 사용
NOT_SUPPORTED 트랜잭션 필요 없음
진행 중인 트랜잭션이 있는 경우 기존 트랜잭션을 일시 중지시킨 후 메서드 실행
메서드 실행이 종료되면 기존 트랜잭션 계속 진행
NEVER 트랜잭션 필요 없음
진행 중인 트랜잭션이 있는 경우 예외 발생
NESTED 트랜잭션 필요
진행 중인 트랜잭션이 있는 경우 기존 트랜잭션에 중첩된 트랜잭션에서 메서드 실행
트랜잭션이 없으면 새로운 트랜잭션 생성

 

 

[ isolation 속성이 가지는 값 ]

 

기능
DEFAULT 데이터베이스에서 제공하는 기존 설정 사용
READ_UNCOMMITED 다른 트랜잭션에서 커밋하지 않은 데이터 읽기 가능
READ_COMMITED 커밋한 데이터만 읽기 가능
REPEATABLE_READ 현재 트랜잭션에서 데이터를 수정하지 않았다면 처음 읽어온 데이터와 두번째 읽어온 데이터가 동일
SERIALIZABLE 같은 데이터에 대해 한 개의 트랜잭션만 수행 가능

 

 

[ /config/mybatis.xml ]

 

...
	<!-- DataSourceTransactionManager 클래스를 이용해 dataSource 빈에 트랜잭션 적용 -->
	<bean id="txManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- 애너테이션을 사용하여 트랜잭션을 적용하기 위해 txManager 빈을 설정 -->
	<tx:annotation-driven transaction-manager="txManager" />
...

 

 

[ /config/service.xml ]

 

...
	<!-- Service 빈의 속성에 DAO 빈을 주입 -->
	<bean id="accService" class="com.spring.account.AccountService">
		<property name="accDAO" ref="accDAO" />
	</bean>
...

 

 

[ src 안에 service 클래스 생성 ]

 

package com.spring.account;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

// @Transactional 을 이용해 Service 클래스의 모든 메서드에 트랜잭션 적용
@Transactional(propagation = Propagation.REQUIRED)
public class AccountService {
	private AccountDAO accDAO;

	// DAO 주입 setter
	public void setAccDAO(AccountDAO accDAO) {
		this.accDAO = accDAO;
	}

	// DAO 의 2개의 SQL 문 실행
	public void sendMoney() throws Exception {
		accDAO.updateBalance1();
		accDAO.updateBalance2();
	}
}

 

Service 빈에서 sendMoney 메서드를 실행할 때 하나라도 에러가 발생하면 rollback 하게 됩니다.

rollback 되지 않고 계좌 이체를 하는데 주는쪽과 받는쪽 둘중에 하나가 에러가 발생하면.. 상상도 못할 상황이 생기겠죠..?

 

여기까지 임미다.

728x90

'개발 > Spring' 카테고리의 다른 글

스프링 REST API - @RestController  (0) 2022.11.18
스프링 인터셉터(Interceptor)  (0) 2022.11.18
메이븐(Maven) 구성요소  (0) 2022.11.17
스프링 @Autowired  (0) 2022.11.16
스프링 애너테이션(Annotation)  (0) 2022.11.16
스프링 마이바티스 연동  (0) 2022.11.16
마이바티스(Mybatis)  (0) 2022.11.15
스프링 JDBC(Java Database Connectivity)  (0) 2022.11.15
스프링 MVC(Model - View - Controller)  (0) 2022.11.15
스프링 프레임워크란?  (0) 2022.11.15