본문 바로가기

스프링

JPA_JTA_하이버네이트 트랜잭션_2

1.     Com.springsource.antlr.jar : Hibernate 구문분석 파서

2.     Com.springsource.javassist : Hibernate javassist바이트코드 생성기 클래스 동적변형

3.     Com.springsource.javax.activation Spring java-mail

4.     Com.springsource.javax.mail : Spring java-mail

5.     Com.springsource.javax.persistence : spring JPA 지원을 위한 클래스 로더 필요

6.     Com.springsource.javax.transaction : JTA

7.     Com.springsource.org.aopalliance : Spring ProxyFactoryBean

8.     Apache.commons.collection : Java 콜렉션 라이브러리 확장

9.     Com.springsource.org.aspectj.tools : AspectJExpressionPointcut 포인트컷 표현식 지원

10.   Com.springsource.org.castor : OXM castor Framework

11.   Com.springsource.org.dom4j : XML파싱

12.   Com.springsource.org.hibernate : 하이버네이트

13.   Com.springsource.org.hibernate.annotation : 하이버네이트

14.   Com.springsource.org.hibernate.annotation.commons : 하이버네이트

15.   Com.springsource.org.hibernate.validator : 하이버네이트

16.   Com.springsource.org.hsqldb : spring 내장형 DataBase

17.   Com.springsource.junit : junit

18.   Com.springsource.slf4j : 수많은 로그파일들의 인터페이스 제공 프레임웍 현재 대세

19.   Commons-logging : Spring-context가 사용

20.   Eclipselink.jar : 이클립스 JPA 구현제품 사용시 사용시

21.   Javax.persistence-api : 줄여서 JPA. JavaSE, EE를 사용하는 응용프로그램에서 관계형 데이터베이스의 관리를 표현하는 자바API

22.   Mail : java-mail

23.   Mockito : 목 프레임워크 중 Mockito

24.   Mysql-connector : Mysql JDBC

25.   Org.springframework.context.support : Spring java-mail

26.   Org.springframework.orm : spring orm

27.   Org.springframework.oxm : Spring OXM(Object XML Mapping) Jaxb .

28.   Spring-aop : 스프링 기능 자체의 aop, Spring ProxyFactoryBean

29.   Spring-bean : 스프링 코어와 함께 의존성 주입 제공 (Core Container)

30.   Spring-context : 스프링 코어, BeanFactory를 확장한 어플리케이션 컨텍스트 구현, 리소스 로드 및 국제화 지원(Core Container)

31.   Spring-core : 다른 스프링 모듈이 사용하는 유틸리티(Core Container)

32.   Spring-expression : EL 확장 Bean속성(배열, 컬렉션 포함).(Core Container)

33.   Spring-jdbc : 스프링이 지원하는 jdbc.

34.   Spring-test.jar

-       @RunWith : Junit 프레임워크의 테스트 실행방법을 확장시 사용.

-       SpringJUnit4ClassRunner : 어플리케이션컨텍스트를 만들고 관리하는 확장 클래스

-       @ContextConfiguration(경로) : 자동으로 만들어줄 어플리케이션 컨텍스트 설정파일

35.   Spring-tx : DuplicateKeyException.class 파일 존재 및 스프링 트랜잭션

36.   transactions-essentials-all : JTA Transaction을 위한 jar

 

* PlatformTransactionManager

> 트랜잭션 경계를 지정하는데 사용한다. 트랜잭션이 어디서 시작하고 종료하는지, 종료할 때 정상종료(commit)인지 비정상 종료(rollback)인지를 결정하는 것이다.

> getTransaction()은 트랜잭션 속성에 따라서 새로 시작하거나 진행 중인 트랜잭션에 참여하거나, 진행 중인 트랜잭션을 무시하고 새로운 트랜잭션을 만드는 식으로 상황에 따라 다르게 동작한ㄷ.

> TransactionDefinition은 트랜잭션의 네 가지 속성을 나타내는 인터페이스다.

> TransactionStatus는 현재 참여하고 있는 트랜잭션의 ID와 구분정보를 담고 있다. 커밋 또는 롤백 시에 이 TransactionStatus를 사용한다.

> 선언적 트랜잭션 방식을 사용할 것이라면 사실 PlatformTransactionManager 인터페이스 사용 방법은 몰라도 상관없다. 다만 이 추상화된 인터페이스를 구현한 트랜잭션 서비스 클래스의 종류를 알고 적절한 것을 선택해서 빈으로 등록하는 방법만 알고 있으면 된다.

> 가끔 테스트에서 트랜잭션을 제어해가면서 테스트 코드를 만들어야 할 경우가 있는데, 그 때는 PlatformTransactionManager를 직접 이용해야 할 수도 있다.

 

* 스프링이 제공하는 DataSourceTransactionManager

> 위 트랜잭션을 사용하려면 DataSource가 스프링의 빈으로 등록돼야 한다.

> 데이터 액세스 기술인 JDBCMybatis로 만든 DAO에 적용할 수 있다.

> 해당 트랜잭션을 빈으로 등록할 때는 적용할 DAO가 사용하는 것과 동일한 DataSource를 빈으로 제공해줘야 한다.

> 사용할 DataSourcegetConnection() 이 호출될 때마다 매번 새로운 Connection을 돌려줘야 한다. ThreadLocal 등을 이용해 트랜잭션을 저장해두고 돌려주는 특별한 기능을 가진 DataSource를 사용하면 안된다.

> 애플리케이션 코드에서 트랜잭션 매니저가 관리하는 Connection을 가져오려면 DataSourcegetConnection() 대신 스프링의 DataSourceUtils 클래스의 스태틱 메소드은 getConnection(DataSource)를 사용해야 한다. 대부분 JdbcTemplate을 이용하면 되기 때문에 직접 가져와 사용할 일은 많지 않다. JdbcTemplate을 사용할 수 없는 코드이거나 DAO 밖에서 현재 Connection을 직접 가져와 사용할 일은 많지 않다. JdbcTemplate을 사용할 수 없는 코드이거나 DAO 밖에서 현재 Connection을 가져와 참조해야 할 때만 주의해서 사용하자.

> JdbcTemplate를 사용하지 않는 레거시(과거로부터 내려오는.. 옛날 Model1 ) DAO 코드를 스프링의 트랜잭션 매니저와 연동해서 동작하게 하려면 어떻게 해야할까?

1) DAO 코드의 Connection을 가져오는 코드를 모두 DataSourceUtils.getConnection()으로 변경

 

2) 레거시 코드가 DataSourcegetConnection()을 직접 호출해서 Connection을 가져오는 경우에 적용할 수 있다. 위와 같이 DaoDataSource 사이에 TransactionAwareDataSourceProxy를 넣어서 레거시 DAO 코드에서 getConnection()을 호출해도 매번 새로운 Connection이 생성되지 않게 할 수 있다. 대신 현재 트랜잭션 매니저가 관리하고 있는, 진행 중인 트랜잭션이 담긴 Connection을 돌려주게 만들 수 있다. DAO에서는 마치 매번 새로운 ConnectionDataSource를 가져오는 것 같지만 실제로는 트랜잭션이 진행 중인 동안에는 매번 같은 Connection을 받게 된다. 자세한 내용은 TransactionAwareDataSourceProxy API 문서를 참고하자.

> 이렇게 스프링의 DataSourceTransactionManager를 사용하는 여러 가지 방법이 있지만, JdbcTemplate이나 마이바티스 SessionTemplate처럼 내부에서 Connection과 트랜잭션 작업을 알아서 처리해주는 템플릿을 사용하는 방법이 제일 좋다.

> 서버가 제공하는 DataSource와 트랜잭션 서비스를 JNDI로 접근해 사용해야 한다면 DatasourceTransactionManager는 사용할 수 없다. 그 때는 JTA를 지원하는 스프링의 트랜잭션 매니저를 사용해야한다. 하나 이상의 DB에 대한 작업을 트랜잭션으로 묶어야 하는 경우에도 DataSourceTransactionManager를 사용하는 대신 JTA를 써야한다.

 

JPA : ORM 표준 인터페이스

 

20. localContainerEntityManagerFactoryBean

> 스프링이 제공하는 컨테이너 관리 EntityManagerFactory를 만들어 준다.

> JavaEE 서버에 배치하지 않아도 컨테이너에서 동작하는 JPA의 기능을 활용할 수 있으며, 스프링이 제공하는 일관성 있는 데이터 엑세스 기술의 접근 방법을 적용할 수 있고, 스프링의 JPA 확장 기능도 활용할 수 있음.

22. persistence.xml : JpaTransactionManager를 사용할 때는 해당 파일을 사용한다.

25. 구현체별로 다름. EntityManagerFactory 생성시 바이트코드 위빙을 사용하지 않겠다는 의미.

28. JPA 구현체 작성

30. generateDdl : DDL (create, drop, alter )을 자동생성해주는 옵션. 애플리케이션이 실행될 때마다 @Entity VO대로 삭제했다 새로 생성함. 운영환경에서는 절대 true로 하면 안됨. 기본값 false

31. showSql true를 통해 SQL 로그 출력. 각 구현체 별로 프로퍼티 설정 다름.

35. JPA를 이용하는 DAO에서는 JpaTransactionManager를 사용한다. 물론 JTA로 트랜잭션 서비스를 이용하는 경우에는 JpaTransactionManager가 필요없다.

> 스프링에서는 LocalContatinerEntityManagerFactoryBean 타입빈을 프로퍼티로 등록해야한다.

 

 

5. name은 스프링 설정에 persistenceUnitName으로 구분하여 호출할 수 있음.(072.JPA편참조)

> JpaTransactionManager를 사용할 때는 transaction-typeJTA로 설정하지 않는다.(생략)

> name default는 위 스프링 설정에 persistenceUnitName을 지정안해서 default

 

쿼리 작성법

 

트랜잭션 테스트

 

트랜잭션 테스트

 

 

JTA 트랜잭션을 이용하려면 트랜잭션 서비스를 제공하는 WAS를 이용하거나 독립 JTA 서비스를 제공해주는 프레임워크를 사용해야한다.

XA DataSource JTA와 분산/글로벌 트랜잭션을 사용하기 위한 설정은 자바 서버마다 다르므로 해당 서버의 매뉴얼을 참고해서 등록하는 방법을 알아둬야한다.

 

2개의 DB에 대해 같은 기능을 가진 DAO를 독립적으로 설정한 예

 

서버에 설정한 DataSource를 사용하여 JtaTransaction한 예

위 설정은 분산 트랜잭션을 위한 XA 프로토콜을 지원하는 XA DataSource이다.

JtaTransactionManager

다른 트랜잭션 매니저와는 다르게 프로퍼티로 DataSourceSessionFactory 등의 빈을 참조하지 않는다.

WAS에 등록된 DataSource를 가져와 JTA를 이용해 트랜잭션을 관리만하므로, 다른 트랜잭션에 비해 설정이 간단하다. DataSource를 알고 있기에 알필요가 없음.

 

JtaTransactionManagerWAS에서 가져올 때 WAS마다 사용하는 것이 다르므로 해당 WAS가 사용하는 JNDI를 지정해줘야한다.

 

13. Atomikos

> JTA는 일반적으로 WAS가 제공하는 서비스를 이용하지만, 톰캣과 같은 JTA가 없는 환경에서도 가능하다.

> ObjectWebJTA 엔진인 JOTMAtomikosTransactionEssentials가 대표적이다.

> 두가지 모두 오픈소스 이므로 자유롭게 가져다 쓸 수 있다.

> Atomikos는 고급기능을 가진 사용 제품인 ExtremeTransactions를 판매하기도 한다.

> 일반적으로 WAS에서 제공하는 XA DataSource를 사용하면 되지만 AtomikosXA를 지원하는 드라이버는 물론이고, 지원하지 않는 드라이버도 XA 드라이버 처럼 사용하게 만들어 준다. 위 예제에서는 MySQL이 제공하는 XA DataSourceMysqlXADataSource를 사용.

14. uniqueResourceName : 다른 DataSource의 리소스 이름과 중복되지 않는 고유한 이름 사용

 

50~53. DB2개 이상이라면 DataSource를 사용하는 DAO도 두 개가 등록돼야 한다.

> 만약 테이블 구조가 같은 두 개의 DB를 중복해서 사용하는 경우라면 DAO 코드가 달라지지 않을 것이다. 이때는 DAO 클래스는 하나만 만들고 DAO 빈 두 개를 등록하면 된다.

60, 61. TransactionManagerUserTransaction을 서버에서 제공해주지 않으므로 atomikos를 빈으로 등록해서 서비스를 이용해야 한다.

66. JtaTransactionManager

> DB가 여러 개라도 JTA를 이용해 글로벌 트랜잭션을 적용할 것이라면 JtaTransactionManager 하나만 등록돼야 한다.(DataSourceTransactionManager, JpaTransactionManager는 필요없음)

> 단 두 개 이상의 DB를 완전히 독립적으로 사용하는 경우라면 두 개 이상의 트랜잭션 매니저를 등록할 수는 있다.

 

 

43. PlatformTransactionManager : 스프링의 트랜잭션 매니저는 모두 Platform~Manager를 구현하고 있다. 따라서 매니저의 종류에 관계없이 동일한 방식으로 트랜잭션을 제어하는 코드를 만들 수 있다.

56. TransactionTemplate: PlatformTran~Manager의 메소드를 직접 사용해도 되지만 try/catch 블록을 써야하는 번거로움이 발생하므로 템플릿/콜백 방식을 이용하면 편리하다.

> TransactionTemplate를 만들 때 TransactionDefinition 오브젝트를 만들어서 파라미터로 제공해주면 된다. 기본 속성을 사용한다면 위의 코드처럼 한번만 만들어 두고 재사용할 수 있다.

> 따라서 Jdbc, Mybatis, JPA, 하이버네이트 중 어떤 것을 이용해도 스프링의 트랜잭션 추상화 기술 덕에 기술에서 독립적인 트랜잭션 코드를 만들 수 있다.

> 대개는 선언적 트랜잭션 방식으로 충분하기 때문에 위 코드는 테스트에서 주로 사용되고, 선언적 트랜잭션으로 만나는 오류에 위처럼 대응할 수 있고, getTransaction(), TransactionStatus 를 이용해 새로 시작된 것인지, 기존 트랜잭션에 참여한 것인지 또는 종료된 것인지를 확인할 수 있다.

 

JDBC, Jpa, HibernateDao

선언적 트랜잭션은 041.AOP_트랜잭션인터셉터_전파속성_사라진어드바이스.docx 편 참조

 

'스프링' 카테고리의 다른 글

트랜잭션_조합_WAS트랜잭션_고급  (0) 2021.02.06
AOP_Aspectj  (0) 2021.02.04
[Hibernate] 하이버네이트_1  (0) 2021.02.02
[JPA] ORM 정의  (0) 2021.02.01
[spring] ibatis  (0) 2021.01.31