스프링에서 제공하는 트랜젝션을 MySQL과 Oracle에다가 적용을 해봤습니다.
제가 잘 이해를 못하는 건지 모르겠는데, Oracle에서는 ReadOnly가 안먹혀요-_-;
MySQL에서는 먹히는데....-_-; Oracle에서는 자체적으로 transaction에서 ReadOnly를 설정하는게 있더군요.
또 Oracle은 트랜젝션기반이라고 하더라구요. 암튼, 참 어렵습니다-_-;
우선 삽질한 코드입니다.
MySQL로 해보았습니다.

필요한 lib입니다.
spring.jar - 스프링할껀데 필요하겠죠?-_-;
commons-logging.jar - 스프링하려면 이눔이 있어야 돼요-_-; 위에 있는 lib와 종속돼요-_-;
ibatis-2.3.0.677.jar - ibatis로 할껍니다. 이게 db연동을 쉽게 해주니까요-_-;
mysql-connector-java-5.1.5-bin.jar - mysql connector가 필요하겠죠!

프로젝트를 만듭시다. TestTransaction이라는 프로젝트를 만듭시다.
최상위 src폴더에다가 applicationContext.xml파일을 만듭시다.

applicationContext.xml
[code]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

 <tx:annotation-driven />
 
 <!-- MySQL용 -->
 <bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource"
  p:driverClassName="com.mysql.jdbc.Driver"
  p:url="jdbc:mysql://db주소"
  p:username="dbid" p:password="dbpw" />
 
   <!--  Transaction manager for iBATIS Daos -->
 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
  p:dataSource-ref="dataSource" />
 
 <!-- SqlMap setup for iBATIS Database Layer -->
 <bean id="sqlMapClient"
  class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
  p:dataSource-ref="dataSource"
  p:configLocation="classpath:SqlMapConfig.xml" />
 
<bean id="insertDataMysql" class="com.mudchobo.TestInsertMysql"
  p:sqlMapClient-ref="sqlMapClient"/>
</beans>
[/code]
TestInsert라는 interface를 작성해봅시다.
TestInsert.java
[code]
package com.mudchobo;

import org.springframework.transaction.annotation.Transactional;

public interface TestInsert {

 @Transactional(readOnly=true, rollbackFor={Throwable.class})
 public void insertData() throws Throwable;
}
[/code]
인터페이스에다가 트랜젝션을 걸어도 되더라구요-_-; 구현되는 모든놈이 저 옵션으로 트랜젝션이 먹히는 듯 합니다. 근데 별로 안좋은 방법인듯한데-_-; 그냥 메소드에 거는게.....-_-; 보면 readOnly옵션에다가 Throwable예외가 발생하면 롤백합니다.

구현해봅시다.
TestInsertMysql.java
[code]
package com.mudchobo;

import java.io.IOException;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class TestInsertMysql extends SqlMapClientDaoSupport implements
  TestInsert {

 @Override
 public void insertData() throws Throwable {
   getSqlMapClientTemplate().insert("insertData");
   System.out.println("mysql에 insert성공");
   throw new IOException();
 }
}
[/code]
insert를 시키고, 강제로 IOException을 발생시켰습니다.

ibatis xml부분을 봅시다.
SqlMapConfig.xml
[code]
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig     
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
 <sqlMap resource="Insert.xml" />
</sqlMapConfig>
[/code]
Insert.xml
[code]
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap     
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Sqlmap">
    <insert id="insertData">
     insert into TESTDATA (DATA) values ('MUDCHOBO')
    </insert>
</sqlMap>
[/code]
보시면 단순 insert를 하고 있습니다-_-;

main부분입니다.
TestTransaction.java
[code]
package com.mudchobo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestTransaction {
 public static void main(String[] args) throws Throwable{
  String[] configLocation = {"applicationContext.xml"};
  ApplicationContext context =
   new ClassPathXmlApplicationContext(configLocation);
 
  TestInsert testInsertMysql =
   (TestInsert) context.getBean("insertData");
  try {
   testInsertMysql.insertData();
  } catch (Throwable e) {
   System.out.println("예외발생");
  }
}
[/code]
이걸 실행하면 트랜젝션이 readOnly이기 때문에 insert하려고 하면 에러가 나버리겠죠.
Connection is read-only. Queries leading to data modification are not allowed; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
요런 에러를 보실 수 있습니다.

Oracle은 다음 장에서-_-;
http://mudchobo.tomeii.com/tt/258 여기에 계속-_-;

 
Posted by 머드초보

댓글을 달아 주세요