본문 바로가기
Spring Framework/study

Spring 트랜잭션 처리 @Transactional

by bloodFinger 2020. 3. 7.

데이터베이스 트랜잭션은 데이터베이스에서 상호작용의 단위 또는 데이터베이스 관리시스템이라 할 수 있다.

연관된 2개 이상의 쿼리를 실행할 때 , 모든 작업이 끝났을 때 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) {
 
        }
    }
}

 

이러한 흐름으로 코드를 작성했다.

//1.로드(적재) - 자바에게 "나 오라클 쓸꺼야" 라고 알려줘야 사용이 가능하다.
Class.forName("oracle.jdbc.driver.OracleDriver");

//2.연결(Connection) - url , 아이디, 패스워드를 적어야 한다.
Connection conn =DriverManager.getConnection("jdbc:orcle:thin:@127.0.0.1:1521:XE", "bitadmin","dkdlxl");
//반복문을 사용해야 한다면 연결 또한 계속해서 해줘야 한다.

//3.준비(statement) - (1) 공간을 만들고 (2) 쿼리문을 작성한다.
Statement stmt = conn.createStatement(); // 공간 만들기
String sql = "SELECT ~~~~~~~~~"; //쿼리문 작성
//ps. 실무에서는 preparedStatement() 를 사용한다!!!

//4.실행
executeUpdate();  //등록, 삭제, 수정 이 가능하다.
execxuteQuery(); // 검색, 목록 이 가능하다.

//5.종료
conn.close();
stmt.close();

 

내가 작성했었던 코드중에 회원정보를 insert

		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "system", "oracle");
                
                String sql = "insert into member(id,passwd,juso,bunho) values(?,?,?,?)";
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, id);
		pstmt.setString(2, passwd);
		pstmt.setString(3, juso);
		pstmt.setString(4, bunho);
        
		int cnt = pstmt.executeUpdate();
		System.out.println(cnt + "등록이 되었습니다.");
		conn.close();
		pstmt.close();

 

JAVA에서 일일이 커밋과 롤백처리를 해서 코딩을 하거나 계속해서 개발자가 연결과 종료를 하는 번거로움이 존재했다.

 

하지만~~~!!!

 

Spring에서는 @Transactional을 활용하여 트랜잭션 처리를 한다.

아주 간편하고 쉽게 트랜잭션을 관리할 수 있게 되었다.

 

<?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:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	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.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<tx:annotation-driven transaction-manager="transactionManager"/>

	<bean id="dataSource" 
		  class="org.apache.commons.dbcp2.BasicDataSource" 
		  p:driverClassName="oracle.jdbc.driver.OracleDriver"
		  p:url="jdbc:oracle:thin:@localhost:1521:xe"
		  p:username="system"
		  p:password="oracle"
		  p:maxTotal="20"
		  p:maxIdle="3"/>
          
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
</beans>

 

이렇게 설정하고나면, 원하는 메소드의 윗부분에 @Transactional을 붙여 간편하게 트랜잭션을 구현할 수 있다.

메소드 전체를 하나의 트랜잭션으로 묶을 수 있다는 것은, @Transactional의 내부 동작이 프록시로 이루어 진다는 것

을 의미한다.

 

@Transactional이 적용되어 있을 경우, 이 클래스에 프랜잭션 기능이 적용된 프록시 객체가 생성된다.

이 프록시 객체는 @Transactional이 포함된 메소드가 호출 될 경우, PlatformTreansactionManager를 사용하여

트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback을 수행한다.

'Spring Framework > study' 카테고리의 다른 글

DAO 패턴은 왜 그렇게 생겼나?  (0) 2020.03.29
Spring Bean Scope ?  (0) 2020.03.06
DI(Dependency Injection) ?  (0) 2019.12.23
IoC Container ?  (0) 2019.12.23
테스트  (0) 2019.12.20