프로그래밍/스프링 & 스프링 부트

스프링 Oracle 트랜잭션 관리 예제

밍구몬 2019. 6. 19. 12:13

스프링에서 트랜잭션을 관리하기 위해서 MyBatis와 Oracle JDBC 또는 HikariCP가 연동되어 있어야 한다.

연동을 한뒤 몇 가지를 세팅해 주어야 한다.

 

pom.xml

		<!-- 트랜잭션 관리를 위한 라이브러리 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

root-context.xml의 Namespaces

다시 source로 돌아가 아래의 내용을 추가해 준다.

	<!-- 트랜젝션 매니저 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<tx:annotation-driven/>

 

예제를 위한 테이블 생성

CREATE TABLE tbl_1(
    data VARCHAR(10)
);

CREATE TABLE tbl_2(
    data VARCHAR(4)
);

tbl_1테이블과 tbl_2테이블을 만들었다. 두 테이블의 길이가 다른 이유는 트랜잭션이 제대로 동작하는지 확인을 하기 위하여 다르게 만들어 주었다.

 

t1Mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="t1Mapper">
	<insert id="insertData">
		<![CDATA[
			INSERT INTO tbl_1 VALUES(#{data})
		]]>
	</insert>
	
	<select id="getData" resultType="String">
		select data from tbl_1
	</select>
</mapper>

t2Mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="t2Mapper">
	<insert id="insertData">
		<![CDATA[
			INSERT INTO tbl_2 VALUES(#{data})
		]]>
	</insert>
	
	<select id="getData" resultType="String">
		select data from tbl_2
	</select>
	
</mapper>

 

txController

package com.wipia.study.controller;

import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class txController {
	
	@Autowired
	SqlSessionTemplate sql;
	
	@GetMapping("/fxTest")
	@Transactional
	public String withdraw(String data) {
		
		if(data!=null) {
			System.out.println(data);
			sql.insert("t1Mapper.insertData",data);
			sql.insert("t2Mapper.insertData",data);
		}
		
		List<String> list1 = sql.selectList("t1Mapper.getData");
		List<String> list2 = sql.selectList("t2Mapper.getData");
		
		return list1.toString()+"<br>"+list2.toString();
	}
	
}

예제이기 때문에 최대한 간단하게 만들기 위하여 Controller만 만들고 데이터를 웹으로 확인하기 위하여 RestController로 만들어 주었다.

http://localhost:8080/fxTest?data=aaaa 이런식으로 데이터를 집어 넣어주게 되면 웹에서 바로 바로 확인이 가능하다.

tbl_2 테이블은 길이가 4이기 때문에 aaaaa를 넣으면 에러가 난다.

두개의 테이블을 확인 해보면 두 테이블 모두 값이 들어가지 않았다.

그 이유는  @Transactional 어노테이션을 사용했기 때문이다. @Transactional 어노테이션을 빼고 테스트하면 아래와 같이 tbl_1 테이블에만 aaaaa가 들어간 것을 볼 수 있다.