ABOUT ME

-

오늘 방문자
-
어제 방문자
-
전체
-
  • @Transactional 세팅 및 사용법
    Spring 2018. 7. 29. 22:05

    역시 세팅이 가장 어려운거 같다..


    개발을 하다 보면 비즈니스 로직을 처리 해야 할때가 있다. 


    여러번의 CRUD작업이 일어나면서 에러가 발생해도 데이터의 정합성을 지켜야 할 때가 있다.(원자성)


    기존에는 아래와 같은 방식으로 처리했다.(프로그램에 의한 트랜잭션 처리)


    하지만 코드도 지져분해지고 타이핑도 많이 해야되는 단점이 있었다.


    그리고 무엇보다 좋은 어노테이션이 있는대 굳이 이렇게 긴소스를 반복해서 쓸 필요가 없다.



    - 개선전 코드


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @Autowired
    private DataSourceTransactionManager txManager;
     
     
    public void updateBoard(Board param) throws Exception {
            
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
            TransactionStatus status = txManager.getTransaction(def);
            
            try{
                sqlSession.insert("insertaaaaaaaa", param);
                sqlSession.update("updatebbbbbbbb", param);
            } catch (Exception ex) {
                txManager.rollback(status);
                throw ex;
            } finally{
                txManager.commit(status);
            }
        }        
    cs









    @Transactional (선언적 트랜잭션)


    - RuntimeException에 대해서만 롤백처리가 가능하다

      (Exception에 대한 설명은 여기 잘 정리되어 있음 http://www.nextree.co.kr/p3239/)


    - MySQL일 경우 Inno일때만 트랜잭션이 작동함


    - proxy를 사용할 때 반드시 public 메소드에 사용해야 한다


    -클래스들이 인터페이스를 사용하는지 확인해야함

     @Transactional 어노테이션 같은경우 Spring AOP를 이용함 , AOP는 기본적으로 Dynamic Proxy를 이용함

     Dynamic Proxy는 인터페이스 기반으로 동작하기 때문에 인터페이스가 없을경우 트랜잭션이 동작하지 않는다.


    -인터페이스없이 트랜잭션을 작동시키려면 CGLib Proxy를 사용하면됨(proxy-target-class="true")

    ex) <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>






    세팅법


    프로젝트구조





    servelet-context.xml

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:context="http://www.springframework.org/schema/context"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:cache="http://www.springframework.org/schema/cache"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd
                            http://www.springframework.org/schema/mvc
                            http://www.springframework.org/schema/mvc/spring-mvc.xsd
                            http://www.springframework.org/schema/cache 
                            http://www.springframework.org/schema/cache/spring-cache.xsd
                            http://www.springframework.org/schema/security 
                            http://www.springframework.org/schema/security/spring-security.xsd  
                            http://www.springframework.org/schema/tx 
                            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                            ">
       
        <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
        <!-- <resources mapping="/resource/**" location="/resources/"/> -->
        <mvc:resources mapping="/resources/**" location="/resources/"/>
        <mvc:resources mapping="/js/**" location="/js/" />
        <mvc:resources mapping="/css/**" location="/css/" />
        <mvc:resources mapping="/imgages/**" location="/imgages/" />
     
     
        <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
        </bean>
        
        <!-- MultipartResolver 설정 -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="maxUploadSize" value="100000000" />
            <property name="maxInMemorySize" value="100000000" />
        </bean>
     
         <tx:annotation-driven transaction-manager="transactionManager" />
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
     
        <context:annotation-config/>
        <context:component-scan base-package="domean"/
        
        <mvc:annotation-driven />
        <mvc:default-servlet-handler />
        
    </beans>
     
    cs


    여기서 dataSource는 DBconect의 bean id이다.



    service.java

    1
    2
    3
    4
    5
    6
     
    public interface MemberService {
     
        public void insertJoinMember(MemberDTO memberInfo) throws SQLException;
            
    }
    cs


    serviceImple.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    @Service
    public class MemberServiceImple implements MemberService{
        
        
        @Autowired
        private MemberDAO memberDAO;
     
        
        @Transactional(rollbackFor =Exception.class
        @Override
        public void insertJoinMember(MemberDTO memberInfo) throws SQLException{
            memberDAO.insertJoinMember(memberInfo);
            String memberSeq=null// 에러발생시킴
            memberDAO.insertJoinMemberAuth(memberSeq);
        }
     
    }
    cs

    rollbackFor : 롤백이 수행되어야 하는 예외클래스를 적어준다
    그외 속성은 http://soulduse.tistory.com/40에 자세히 나와있다.






    'Spring' 카테고리의 다른 글

    Swagger란?  (0) 2018.09.17
    데이터베이스 연동  (0) 2018.09.04
    Spring Security 중복로그인 막기  (0) 2018.09.04
    Spring Security 태그  (0) 2018.09.04
    Mybatis - mapUnderscoreToCamelCase  (1) 2018.07.30

    댓글

Designed by Tistory.