[에러] no matching editors or conversion strategy found


1. 환경                                                         

                         

 Spring 

 4.3.6 (SpringMVC 기준)

 Java 

 1.8.0_92

 Tomcat 

 8.0.42

 암호화 관련 라이브러리

 jasypt-spring31-1.9.2.jar

 jasypt-1.9.2.jar

 bcprov-jdk15on-1.56.jar

 bcpkix-jdk15on-1.56.jar

            


2. 에러 메세지


 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configurationEncryptor' defined in file [C:\sample\server\apache-tomcat-8.0.42\webapps\sample-pjt\WEB-INF\classes\META-INF\config\context-datasource-dev.xml]: Cannot resolve reference to bean 'environmentVariablesConfiguration' while setting bean property 'config'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'environmentVariablesConfiguration' defined in file [C:\Sample\server\apache-tomcat-8.0.42\webapps\sample-pjt\WEB-INF\classes\META-INF\config\context-datasource-dev.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'java.security.Provider' for property 'provider'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.security.Provider' for property 'provider': no matching editors or conversion strategy found



3.  AS-IS 설정/소스

 

    - database 관련 설정파일 context-datasource.xml 파일 내 프로퍼티 파일 암호화 환경 설정

   

   <!-- 암호화  provider 선언 -->

    <bean id="bouncyCastleProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider"/>

    <!-- 암호화  환경 설정 -->

    <bean id="environmentVariablesConfiguration"

        class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">

        <property name="provider" value="bouncyCastleProvider" />

        <property name="algorithm" value="PBEWITHSHA256AND128BITAES-CBC-BC" />

        <property name="passwordEnvName" value="APP_ENCRYPTION_PASSWORD" />

    </bean>

    <!-- 암호화 실행 모듈 선언 -->

    <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">

        <property name="config" ref="environmentVariablesConfiguration" />

        <property name="password" value="easyframework" />

    </bean> 



4. 에러 원인


    - environmentVariablesConfiguration bean에서는 bouncyCastleProvider 라는 bean을 참조로 하여 암호화 환경을 설정하고 있는데,

       이때, provider 속성에 해당하는 참조 bean bouncyCastleProvider를 'ref'로 선언해야 하는 데 value 로 선언하여 이를 provider 속성에

       String 값으로 넣으려 하다가 나는 에러다. 객체를 참조하는 부분이니 value 가 아니라 ref로 바꿔줘야 정상 동작한다. ㅎㅎㅎ 이런 실수를 ㅜ

       처음보는 에러 메세지여서 정리해둔닷



5. 해결


    - 아래와 같이 설정 변경해주니, 정상 기동하였다.


  <!-- 암호화  provider 선언 -->

    <bean id="bouncyCastleProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider"/>

    <!-- 암호화  환경 설정 -->

    <bean id="environmentVariablesConfiguration"

        class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">

        <property name="provider" ref="bouncyCastleProvider" />

        <property name="algorithm" value="PBEWITHSHA256AND128BITAES-CBC-BC" />

        <property name="passwordEnvName" value="APP_ENCRYPTION_PASSWORD" />

    </bean>

    <!-- 암호화 실행 모듈 선언 -->

    <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">

        <property name="config" ref="environmentVariablesConfiguration" />

        <property name="password" value="easyframework" />

    </bean> 




'Spring' 카테고리의 다른 글

(작성중) dispatcher-servlet.xml 설정  (0) 2017.04.16
spring - profile  (0) 2017.03.19
[Spring] Transaction 관리  (0) 2017.03.12
Spring - BeanNameViewResolver  (0) 2017.01.29


프로젝트에서 전체 프로젝트 환경 구성을 맡게 되었다. 

프로젝트 구조를 어떻게 가져갈지 고민하고, 패키지 구조, 공통 제공 기능 등을 구상해야 했다. 

처음해보기도 했고, 아직 많~~~~이 부족하다는 걸 매순간 깨닫는 작업이었다..  

프로젝트 끝나기 전까지 내가 스스로 프로젝트를 좀 더 효율적으로 할 수 있는 부분을 캐치해내고, 적용해보는 부분이 생기도록 고민해봐야겠다!


우선, 오늘은 Spring 설정 부분을 정리해두려 한다. 

구성한 프로젝트 환경은 아래와 같다


 - JAVA: JDK 1.8

  - IDE: Eclipse Mars2 (4.5)

  - WAS: Tomcat 8.0.42 

  - DB: Oracle 11g

  - Build: Maven 3.3.9

  - Framework: Spring 4.3.6 , 사내프레임워크

 


기존 시스템 재구축 성격의 프로젝트라, 기본적인 tools 업그레이드와, 프레임워크 버전 현행화가 요새 주된 작업이다.

버전 업그레이드라 생각해서 처음부터 구축하는 것 보다 낫겠지 싶었는데, 더 어려운 것 같다.. 호환성이 안맞아 깨지는 부분이 생기고 ㅜ


AS-IS 시스템은 Spring 3.1 버전을 쓰고 있었다.


Spring 4.3.x 에 맞게 dispatcher-servlet.xml 파일을 수정했다. 처음엔 뜬구름 잡듯이 이해됬었는데, 차장님한테 질문하고나니

그래도 흐름이 쭉 잡힌 것 같다. 잘정리해놔야지!


_____________________________________________________________________________________________________________________________

# Spring 설정: dispatcher-servlet.xml


  dispatcher-servlet에서 기본적으로 설정 고려해야 하는 항목들은 아래와 같다고 생각한다.

  

  1.component 스캔

   2.MVC 설정 = interceptors, adpater, handler

   3.Resolver 설정


 '화면'단에 적용할 설정들을 모아놓는 곳이기 때문에 기본적으로 위의 설정들은 들어가야 한다. 


1) dispatcher-servlet.xml

  

    - 톰캣 서버를 기동시키면 기동로그에 dispatcher-servlet 파일이 로딩되는 부분이 보인다.

    - root Context 초기화가 이루어진 다음, 이제 WebApplication Context가 초기화될 차례다.

    -  WebApplication Context가 초기화되면서, dispatcher-servlet.xml 파일에 선언한 bean 들이 등록된다.


정보: Initializing Spring FrameworkServlet 'sample'

| [INFO ] 20:45:38.727 [o.s.w.servlet.DispatcherServlet] [localhost-startStop-1]   -FrameworkServlet 'sample': initialization started 

| [INFO ] 20:45:38.732 [o.s.w.c.s.XmlWebApplicationContext] [localhost-startStop-1]   -Refreshing WebApplicationContext for namespace 'sample-servlet': startup date [Sun Apr 16 20:45:38 KST 2017]; parent: Root WebApplicationContext 

| [INFO ] 20:45:38.732 [o.s.b.f.x.XmlBeanDefinitionReader] [localhost-startStop-1]   -Loading XML bean definitions from class path resource [META-INF/dispatcher-servlet.xml]  



  (1) component 스캔 작업


      - dispatcher-servlet.xml 파일 내 컴포넌트 스캔 셋팅은 아래와 같다. 


<?xml version="1.0" encoding="UTF-8"?>

<beans  xmlns:context="http://www.springframework.org/schema/context" 

            xsi:schemaLocation=" http://www.springframework.org/schema/context 

                                         http://www.springframework.org/schema/context/spring-context.xsd ">


<context:component-scan base-package="com.sampleframework, com.sampleCompany.sample" use-default-filters="false">

   <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>    

</context:component-scan>  



      ▶ Spring이 @Component 또는 @Component를 메타 어노테이션으로 갖고 있는 어노테이션(@Controller, @Repository, @Service)이 

          붙은 클래스들을 빈으로 등록한다.

      ▶ 스캔 범위: 보통 공통빈(persistence, service) 설정 정보는 Application context에, web layer 단의 빈(controller)들WebApplicationContext에 

                        저장한다.

      ▶ stereotype annotation: 클래스에 붙어 해당 클래스가 컴포넌트 스캔 대상이고, 스프링에 의해 관리될 것임을 명시한다. 

      ▶ base-package: 설정한 패키지 내에서 컴포넌트 스캔을 수행한다. 스캔 범위 지정

      ▶ use-default-filters: 아무 설정을 안할 경우 default로는 모든 stereo type 스캔한다. 개별적으로 특정 빈만 스캔하려는 경우 

                                   해당 설정을 false로 해주고, 특정 빈을 include filter 설정해주어야 한다.



      ▶ sts 의 spring explorer를 통해 bean 로딩 확인 (프로젝트 패키지명은 모자이크 처리함)



[ 이미지1 - component-scan의 use-default-filters 설정을 주지 않은 경우, base-package내 컴포넌트들을 모두 스캔하고 있다]



                   [ 이미지2 - component-scan의 use-default-filters 설정을 false로 주고, Controllerㄹ 컴포넌트만 include 설정 한 경우, base-package내 

                                  @Controller 컴포넌트들만 스캔하고 있다]




(2) spring MVC 설정


    - spring MVC를 활성화하기 위해 아래와 같은 설정을 해준다.


    - 보통 설정들을 copy해서 쓰기 때문에 실제로 이 설정이 정확히 어떤 역할을 하는지 몰라 그냥 그대로 쓰는 경우가 많다.

      그러다 보면 사용하지 않는 설정들도 다 포함되어 설정파일만 비대해지게 된다. 


      STS를 별도로 설치하여 spring explorer 뷰를 활용하여 실제 설정을 적용했을 때 어떤 변화가 일어나는 지 확인해 보았다. (강추!)

      (eclipse Mars2 4.5 버전에서는 sts 플러그인 설치 시, 기존 내장되어 있는 maven 의 m2e와 충돌이 나는지.. 설치 후 

       maven 도 안되고, sts 기능도 사용이 불가했다...버그인것 같은데 레퍼런스가 거의 없다 ㅜㅜ. sts 중 maven 과 겹치는 부분은 제외한 채

       설치해도 같은 결과가 반복됬다.....eclipse를 밀기를 몇번 ^^;; 그냥 sts 를 별도로 설치해서 확인했다)


<mvc:annotation-driven />  


    ▶@Controller 와 @RequestMapping 사용 활성화

    ▶@Controller들에게 요청을 전파하기 위한 HandlerMapping(default: RequestMappingHandlerMapping)과          

       HandlerAdapter(default: RequestMappingHandlerAdapter)를 등록


         - RequestMappingHandlerMapping 역할: 요청들을 해당 annotation이 걸린 컨트롤러 method로 매핑

          

    ▶ HandlerExceptionResolver 등록

  


[이미지3 - mvc:annotation-driven 설정을 해준 경우, 위와 같이 handlerAdapter가 자동으로 등록되었다. 더 깊게 확인은 못해봤지만,       

              AnnotationDrivenBeanDefinitionParser라는 애가 파싱을 담당하나 보다.]





(3) MVC - interceptor 설정 


(4) MVC - adapter 설정


(5) MVC - resolver 설정






__________________________________________________________________________________________________________________________________________________________

** 본 포스팅에 대해 수정해야할 부분이나 추가 의견 등이 있으신 분들은 댓글 달아주세요. 언제나 환영입니다 :) 

** 본 포스팅을 reference 자료로 참고하실 분들은 출처를 꼭 밝혀주시기 바랍니다.



 

      


'Spring' 카테고리의 다른 글

[에러] no matching editors or conversion strategy found  (0) 2017.04.20
spring - profile  (0) 2017.03.19
[Spring] Transaction 관리  (0) 2017.03.12
Spring - BeanNameViewResolver  (0) 2017.01.29

 [Spring] 


# Profile 기능


1) spring profile 이란?


    - Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain 

        environments. Any @Component or @Configuration can be marked with @Profile to limit when it is loaded

     - 어플리케이션의 여러 환경들을 설정해놓고 필요시마다 원하는 환경으로 선택 구동하게끔 설정해주는 기능.

     - Spring 3.1 부터 등장한 기능으로, 환경 별로 다른 profile을 적용할 수 있게 하는 기능.

     - 주로 어플리케이션 개발/테스트/운영 환경 설정에 자주 쓰인다.



2) 설정 방법


     (1)application context 의 beans 에 환경 별 profile 등록


 <beans profile="dev">

     <bean id="" class="">

          <property name="" value=""/>             --> 개발환경 profile

     </bean>

 </beans>

 <beans profile="prd">

<bean id="" class="">

          <property name="" value=""/>             --> 운영환경 profile

     </bean>

 </beans>    



    (2) 등록한 bean 중 구동할 profile 선택 활성화

          

         방법1) JVM property로 설정

                  : tomcat 서버 더블 클릭 > open launch configuration > arguments 탭 > VM arguments 에 아래 설정 추가 

                                

 -Dspring.profiles.active=dev       --> 개발환경 용 profile 활성화 시 



         방법2) web.xml 에 설정


 <context-param>

    <param-name>spring.profiles.active</param-name>

    <param-value>dev</param-value>

 </context-param>



         방법3) annotation 으로 설정

                       : 설정 파일에 각 환경별로 설정한 후, @Configuration + @Profile("설정한환경 value") 로 구동할 수 도 있다.

                                                                                  @ContextConfiguration("/context-common.xml") + @ActiveProfiles("dev")  

                                                                                       --> junit 등으로 test case 돌릴 때 유용

   

 @Configuration 

 @Profile("dev") 

 public class SampleClass {

   .....

 }




         방법4) programming으로 설정

                   : 어플리케이션 구동 전SpringApplication.setAdditionalProfiles() 를 사용하거나

                     , spring이 제공하는 인터페이스 ConfigurableEnvironment 를 통해 설정하여  활성화 할 profile 설정





__________________________________________________________________________________________________________________________________________________________

** 본 포스팅에 대해 수정해야할 부분이나 추가 의견 등이 있으신 분들은 댓글 달아주세요. 언제나 환영입니다 :) 

** 본 포스팅은 아래의 reference 들을 참고하여 내용을 덧붙인 글입니다. 혹시, 문제가 되는 경우 알려주시면 조치하도록 하겠습니다.

** 본 포스팅을 reference 자료로 참고하실 분들은 출처를 꼭 밝혀주시기 바랍니다.


  - http://docs.spring.io/spring-boot/docs

  - http://www.lesstif.com/

 

'Spring' 카테고리의 다른 글

[에러] no matching editors or conversion strategy found  (0) 2017.04.20
(작성중) dispatcher-servlet.xml 설정  (0) 2017.04.16
[Spring] Transaction 관리  (0) 2017.03.12
Spring - BeanNameViewResolver  (0) 2017.01.29

# Spring - Transaction


1) Transaction 이란?


    - 데이터베이스 관리 시스템에서의 상호작용 단위

    - 데이터베이스 작업 단위

    - 하나 이상의 SQL 문장들로 이루어진 논리적인 작업 단위

    - 데이터베이스 처리 작업이 모두 완료되거나 모두 취소되게 되는 작업의 단위


     --> 실제로 INSERT, UPDATE, DELETE 등 도 하나의 트랜잭션으로 볼 수 있다.  예를 들어, 10개의 데이터를 삭제 하는 경우 3개를 삭제한 후,

          4개째에서 오류가 발생하여 삭제가 안되면, 기존의 삭제 된 3개도 rollback 한다. (또는 3개만 정상 삭제 처리됬다고 사용자에게 알림을 

          주기도 한다)


     --> 여러개의 DML 문을 복합적으로 사용하여 하나의 트랜잭션으로 묶는 경우도 많다. DELETE 후 INSERT 하는 경우가 그 예이다. 



2) Transaction의 특성 'ACID'

  

    - 원자성(Atomicity): 더이상 분리할 수 없는 하나의 작업 단위로, 모두 완료되거나 모두 취소되어야 한다.


    - 일관성(Consistency): 사용되는 데이터는 모두 일관되어야 한다.


    - 고립성(Isolation): 하나의 트랜잭션이 접근하고 있는 데이터는 다른 트랜잭션으로 부터 격리되어야 한다. 

                             트랜잭션 과정 중간의 데이터는 확인 불가.


    - 영구성(Durability): 트랜잭션이 종료되면, 그 결과는 영구적으로 적용되어야 한다.


       --> 실제론, 성능향상을 위해 각 특성을 완화하는 경우도 많다. 



 3) Transaction, 뭐 때문에 쓰는건지?? 목적?


     트랜잭션을 쓰는 이유는 데이터 무결성(integrity) 때문이다. 

     쿼리 하나가 실패하면, 데이터베이스 시스템은 전체 트랜잭션 또는 실패한 쿼리를 롤백한다. 

     은행에서 내계좌에서 돈이 빠져나간 후 '송금' 처리하는 작업을 순차적으로 처리할 때, 중간에 쿼리가 실패하여

     내 계좌에서는 돈이 빠져나갔는데, 송금 처리는 되지 않는 경우가 발생 할 수 있다. 이런 경우 데이터 무결성이 깨지게 된다. 

     이러한 문제를 방지하기 위해서, 즉 데이터 무결성을 지키기 위해 트랜잭션을 사용한다.

     

     --> 실제로 트랜잭션은 보통 아래와 같은 과정을 거쳐 SQL 언어로 데이터베이스 내에서 실행된다.

            * Begin the transaction

            * Execute several queries  (DB 갱신 전)

            * Commit the transaction  (성공적인 트랜잭션 수행 후, DB 갱신)



  4) Transaction 설정


      사실 이 부분을 정리해 두려고, 이 포스팅을 작성하기 시작했다. 프로젝트 때 delete 후 insert 하는 업무 등을 처리하기 위해

      트랜잭션을 걸어줬었다. 실제로 어떻게 설정하는지 아래에 정리해 보았다.


      트랜잭션을 설정하는 방법은 하나만 있는 것이 아니다. Java의 트랜잭션 API (JTA)를 쓸 수도 있고, Spring이 제공하는 트랜잭션

      기능 등을 이용할 수 도 있다. 


      우선 이번 포스팅에서는 Spring에서 제공해주는 트랜잭션 관리 방법을 정리하고자 한다. 



 (4.1) Transaction 관련 스키마 설정

      

<?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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd

       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">



 (4.2) TransactionManager 설정


         - 우선, datasource 쪽 설정파일에 transactionmanager 설정을 해준다.

         - 이번 프로젝트에서는, resources/spring/context-datasource.xml 이라고 DB 관련 설정을 한 데 모아놓았다. 트랜잭션도 이곳에 설정!

         - class: spring 프레임워크에서 제공하는 DataSourceTransactionManager 클래스 (platformTransactionManager)


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

     <bean id="transactionManagerSample"       

              class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

         <property name="dataSource" ref="dataSourceSample" />

     </bean>

tx:annotation-driven

 어노테이션에 기반한 트랜잭션의 동작을 활성화한다

 @Transcational이 붙은 bean 만 찾음 (applicationContext에서)

   --> 만약 webApplicationContext에 tx:annotaion-driven을 설정해놓으면 서비스가 아니라 controller

         에서만 @Transcational이 붙은 bean을 찾는다

transaction-manager

 default 값: transactionManager

 default 값 'transactionManager' 가 아닌 다른 이름을 사용하는 경우에만 설정 

 proxy-target-class

 proxy 모드에만 적용된다.
 @Transactional 어노테이션이 붙은 클래스에 어떤 타입의 트랜잭션 프록시를 생성할 것인지 제어한다.    proxy-target-class 속성을 true로 설정했다면 클래스기반의 프록시가 생성된다.
  --> 트랜잭션은 원래 interface에다가 걸게끔 나왔는데, controller 클래스에 걸려는 사용자들이 늘어나

       면서 기본 클래스에도 transaction을 걸 수 있도록 설정할 수 있게 되었다. 

 proxy-target-class 속성을 생략하거나 false로 설정하면 표준 JDK 인터페이스 기반의 프록시가 생성된다


 DataSourceTransactionManager 클래스

 역할

  - JDBC 3.0을 통해 트랜잭션 지원
  - 특정 datasource 로 부터 현재 쓰레드까지 JDBC connection 을 바인딩 한다 

 주요 메서드

  - setDataSource, getDataSource

  - doBegin

  - doCommit

  - doRollback



 (4.3) @Transactional 어노테이션 설정


        - 인터페이스 정의, 인터페이스의 메서드, 클래스 정의, 클래스의 퍼블릭 메서드 앞에 @Transactional 어노테이션을 설정 할 수 있다.

        - 트랜잭션을 적용하려는 메서드 등에 설정. 특정 메서드에서만 트랜잭션을 사용하는 경우, 인터페이스 혹은 클래스 전체에 거는 것보다

          특정 메서드에만 걸어주는 것이 성능면에서 효율적이다.


/**

* 데이터 일괄 삭제 후 insert 서비스

* @param CommandMap commandMap, String jasonData

* @return Map<String, Object> resultMap

* @throws Exception

*/

@SuppressWarnings({ "unchecked", "rawtypes" })

@RequestMapping(value = "/ajaxUpdateList", method = RequestMethod.POST)

@Transactional

public @ResponseBody Map<String, Object> updateFpFunctionList(

@RequestParam(value = "rowList", required = true) String jasonData, CommandMap commandMap)

throws Exception {

...... 생략

        

// 기존 데이터 일괄 삭제

mapDao.delete("groupId.artifactId.sample_delete_all", commandMap.translateMap());

   

// 업데이트 데이터, 한 row 씩 INSERT 처리

for (Object object : array) {

mapDao.update("groupId.artifactId.sample_insert", (Map) object);

}

       ..... 

}

return resultMap;

}



 @Transactional 속성

 propagation

 

  

 isolation

 

 

 readOnly 

 boolean

 읽기/쓰기 트랜잭션? or 읽기 전용 트랜잭션?  

 성능을 최적화하기 위해 사용할 수도 있고 특정 트랜잭션 작업 안에서 쓰기 작업이 일어나는  것을 의도적으로 방지하기 위해 사용하기도 함. 

 timeout

 int 

 트랜잭션 타임 아웃

 정해진 시간 내에 메소드 수행이 완료되지 않을 경우 rollback함

 default 값: -1 ( = timeout 수행하지 않음)

 rollbackFor

 

 정의된 exception에 대해서는 rollback을 수행함 

 noRollbackFor

 

 정의된 exception에 대해서는 rollback을 수행하지 않음

( ** propagation 과 isolation 개념은 아직 정확히 이해가 안되어 작성하지 못했다.. 



 (4.4) Transaction 이 잘 걸렸나 테스트


       - 위와 같이 트랜잭션 설정을 해놓았으니, 이제 정말 잘 설정된 것이 맞는 지 테스트를 해 볼 차례다.

         테스트는 jUnit 테스트로 진행해보았다.

       

@WebAppConfiguration

@RunWith(SpringJUnit4ClassRunner.class)

@ActiveProfiles("dev")

@ContextConfiguration(locations={"classpath*:/spring/context-*.xml", "classpath*:/config/dispatcher-servlet.xml"})

public class TestTransaction {


    @Autowired

private TransactionTest TransactionTest;

    

    @Autowired

private GenericDao<Map<String, Object>> mapDao;

@SuppressWarnings({ "unchecked", "rawtypes" })

@Test

public void test() throws Exception {

Map map = new HashMap();

map.put("YEAR", "2017");

map.put("userId", "testID");

map.put("name", "tester");

//삭제 후 테스트

mapDao.delete("groupId.artifactId.sample_delete", map);

//중복키 INSERT 테스트

try{

TransactionTest.testDuplecateInsert(map); --> testDuplecateInsert 클래스에서는 같은 데이터(map)를 insert 시도

                                                                                        --> 예외 발생(SQLServerException)

}

catch(Exception e){

//예외 발생 시 INSERT 여부 파악

List<Map<String, Object>> list = mapDao.list("groupId.artifactId.sample_select", map);

if(list.size() == 0 ) {

   System.out.println( "rollback success!" );

}else{

   System.out.println( "rollback fail!" );

}

}

}


위의 class를 test 클래스로 만들고 공통모듈 'aop'쪽에 TestTransaction.java 라는 클래스를 만들어 실제 testDuplecateInsert 메서드를 수행했다.

위 클래스에서 마우스 우측 > run as > junit Test 를 클릭하면 junit test 가 수행된다. (junit 테스트 관련 정리는 다음 포스팅에~!!)


그, 결과 삭제 후 insert 도중 exception이 발생하여 예외가 발생하기전에 insert 수행 처리 되었던 row까지 전부 rollback 되었다. 

트랜잭션 rollback 성공!!


<-- 발생 Exception: SQLServerException -->

com.microsoft.sqlserver.jdbc.SQLServerException: PRIMARY KEY 제약 조건 'TB_SAMPLE'을(를) 위반했습니다. 개체 'dbo.TB_SAMPLE'에 중복 키를 삽입할 수 없습니다. 중복 키 값은 (2017, testID, tester)입니다.

at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196)

at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1454)

at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:388)

at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:338)

at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4026)

at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1416)

at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:185)

at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:160)

at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:320)

at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

at net.sf.log4jdbc.PreparedStatementSpy.execute(PreparedStatementSpy.java:418) 


     ....... 생략

 rollback success!



트랜잭션을 무작정 걸기 전에, 왜 트랜잭션을 쓰는지, 어디에 걸어야 성능측면에서 가장 효율적일지 등의 고민을 해야할 것 같다. 

설정 후 테스트도 충분히 해보고~!


__________________________________________________________________________________________________________________________________________________________

** 본 포스팅에 대해 수정해야할 부분이나 추가 의견 등이 있으신 분들은 댓글 달아주세요. 언제나 환영입니다 :) 

** 본 포스팅은 아래의 reference 들을 참고하여 내용을 덧붙인 글입니다. 혹시, 문제가 되는 경우 알려주시면 조치하도록 하겠습니다.

** 본 포스팅을 reference 자료로 참고하실 분들은 출처를 꼭 밝혀주시기 바랍니다.


  - https://ko.wikipedia.org/wiki

  - https://spring.io/guides/gs/managing-transactions/

  - https://blog.outsider.ne.kr/869





'Spring' 카테고리의 다른 글

[에러] no matching editors or conversion strategy found  (0) 2017.04.20
(작성중) dispatcher-servlet.xml 설정  (0) 2017.04.16
spring - profile  (0) 2017.03.19
Spring - BeanNameViewResolver  (0) 2017.01.29

+ Recent posts