티스토리 뷰

반응형

★관련 링크

Spring과 DB이야기 - 1. DataSource와 JdbcTemplate

Spring과 DB이야기 - 2. JdbcTemplate에서의 UPDATE, INSERT



 데이터베이스 트랜잭션(Database Transaction)은 데이터베이스에서 상호작용의 단위라고 할 수 있다. 연관된 두 개 이상의 쿼리를 실행할 때, 모든 작업이 끝났을 때 COMMIT을 수행하고 중간에 오류가 발생하면 ROLLBACK하는 것이 기본이다. (트랜잭션을 잘 모른다면 여기를 클릭)


 

 트랜잭션을 JAVA에서 구현한다면 아래와 같을 것이다.


Connection conn = null;
try {
	conn = DriverManager.getConnection(jdbcUrl, user, pw);
	conn.setAutoCommit(false);
	/*
		...쿼리 실행..
	 */
	conn.commit();
} catch (SQLException e) {
	if(conn!=null) {
		try {
			conn.rollback();
		} catch (SQLException e1) {

		}
	}
} finally {
	if(conn!=null) {
		try {
			conn.close();
		} catch (SQLException e) {

		}
	}
}


 AutoCommit 설정값을 바꾸어 트랜잭션 처리를 구현한 것을 확인할 수 있다. 한편, Spring에서는 @Transactional을 활용하여 트랜잭션 처리를 한다. @Transactional 어노테이션 사용을 위해, bean 설정은 아래와 같이 하면 된다.


<beans xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value=""/> <property name="user" value="user"/> <property name="password" value="pwd"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> <tx:annotation-driven transaction-manager="transactionManager"/> </bean> </beans>


 JAVA 소스코드에서 직접 설정하는 경우, 적절한 @bean을 생성한 뒤 @EnableTransactionManagement를 이용하면 된다.


 이렇게 설정하고나면, 원하는 메소드의 윗부분에 @Transactional을 붙여 간편하게 트랜잭션을 구현할 수 있다. 메소드 전체를 하나의 트랜잭션으로 묶을 수 있다는 것은, @Transactional의 내부 동작이 프록시(Proxy)로 이루어진다는 것을 뜻한다. 


@Transactional
public void something (int a) {
    ...
}


 @Transactional이 적용되어 있을 경우, 이 클래스에 트랜잭션 기능이 적용된 프록시 객체가 생성된다. 이 프록시 객체는 @Transactional이 포함된 메소드가 호출 될 경우, PlatformTransactionManager를 사용하여 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 한다.


 정상 여부는 RuntimeException이 발생했는지 기준으로 결정되며, RuntimeException 외 다른 Exception(대표적으로 SQLException이 있다.)에도 트랜잭션 롤백처리를 적용하고 싶으면 @Transactional의 rollbackFor 속성을 활용하면 된다.

(참고: JAVA의 Exception(예외)이란 무엇인가)



 마지막으로, 트랜잭션 전파에 대해 알아보자. 트랜잭션을 처리하다 보면 자주 발생하게 되는 상황이 있다. 바로 트랜잭션 동작 도중 다른 트랜잭션을 호출(실행)하는 상황이다. 피호출 트랜잭션의 입장에서는 호출한 쪽의 트랜잭션을 그대로 사용할 수도 있고, 새롭게 트랜잭션을 생성할 수도 있다.


 전자의 경우 중간에 오류가 발생하면 모든 트랜잭션이 롤백될 것이고, 후자의 경우 오류가 발생한 트랜잭션이 롤백 될 것이다. 이러한 트랜잭션 관련 설정은 @Transactionalpropagation 속성을 통해 지정할 수 있다.


@Transactional(propagation = Propagation.REQUIRES_NEW)
public void something (int a) {
    …
}

 propagation에 지정할 수 있는 값은 다양하다. 그것들을 간단히 정리하면 아래와 같다.


REQUIRED: 현재 진행중인 트랜잭션이 있으면 그것을 사용하고, 없으면 생성한다. [DEFAULT 값]


MANDATORY: 현재 진행중인 트랜잭션이 없으면 Exception 발생. 없으면 생성한다.


REQUIRES_NEW: 항상 새로운 트랜잭션을 만듦 (트랜잭션을 분리)


SUPPORTS: 현재 진행중인 트랜잭션이 있으면 그것을 사용. 없으면 그냥 진행.


NOT_SUPPORTED: 현재 진행중인 트랜잭션이 있으면 그것을 미사용. 없으면 그냥 진행.


NEVER: 현재 진행중인 트랜잭션이 있으면 Exception. 없으면 그냥 진행.






-끝-



★관련 링크

Spring과 DB이야기 - 1. DataSource와 JdbcTemplate

Spring과 DB이야기 - 2. JdbcTemplate에서의 UPDATE, INSERT





출처 및 참고 최범균, 

『스프링4 프로그래밍 입문』, 가메출판사(2015) 

https://docs.spring.io/ 

https://ko.wikipedia.org/




«   2022/05   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
글 보관함
Total
800,128
Today
22
Yesterday
127