Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- tibero
- gradle
- BPMN
- NCP
- nginx
- nodejs
- JPA
- docker
- JavaScript
- kubectl
- useEffect
- jetbrains
- Spring
- LOG4J
- springboot
- MySQL
- VSCode
- Java
- database
- react
- dbeaver
- mybatis
- gson
- intellijIDEA
- log4j2
- Windows
- IntelliJ
- wildfly
- Git
- Kubernetes
Archives
- Today
- Total
두 손끝의 창조자
Spring Transaction Management 본문
- 핵심 Interface
- PlatformTransactionManager
- getTransaction()
- commit()
- rollback()
- TransactionDefinition
- 트랜잭션 4가지 속성
- 구현체
- DataSourceTransactionManager
- TransactionAPI를 이용해서 관리
- 트랜잭션을 적용할 datasource가 빈으로 등록되어 있어야 함
- JDBC과 SqlMap으로 만든 DAO에 적용가능함
- 트랜잭션을 적용할 DAO가 사용하는 것과 동일한 datasource를 빈으로 제공해야 함
- Datasource를 getConnection()이 호출될때마다 매번 새로운 Connection을 돌려줘야 함
- ThreadLocal 등을 이용해 트랜잭션을 저장해두고 돌려주는 특별한 기능을 가진 DataSource를 사용하면 안됨
- 애플리케이션 코드에서 트랜잭션 매니저가 관리하는 Connection을 가져오려면 DataSourceUtils.getConnection(DataSource)를 사용해야 함
- JDBCTemplate 내부에서 현재 진행중인 트랜잭션을 가져올 때 이 메소드를 씀
- DAO 밖에서 현재 Connection을 가져와서 참조해야 할 경우만 주의해서 사용할 것
- JDBC Template를 사용하지 않는 레거시 DAO에서 트랜잭션 매니저와 연동하려면
- 레거시 DAO의 getConnection을 DataSourceUtils.getConnection(DataSource)로 모두 변경
- DAO와 DataSource 사잉에 TransactionAwareDataSourceProxy를 넣ㅇ어서 DAO에서 getConnection을 해도 현재 트랜잭션의 커넥션을 가져오게 할 수 있음
- 제한
- 서버가 제공하는 DataSource와 트랜잭션 서비스를 JNDI로 접근해야 한다면 사용할 수 없음
- JTA를 지원하는 스프링 트랜잭션 매니저를 이용
- JtaTransactionManager
- 하나 이상 DB 또는 트랜잭션 리소스가 참여하는 글로벌 트랜잭션을 적용해야 할 때
- 트랜잭션 서비스를 제공하는 WAS를 이용하거나, 독립 JTA 서비스를 제공해주는 프레임워크를 사용해야 함
- DataSource도 서버에 등록된 XA DataSource를 사용해야 함
- DB가 하나라면 트랜잭션 매니저도 하나만 등록돼야 함
- DB가 여러 개라도 JTA를 이용해 글로벌 트랜잭션을 적용 할 것 이라면 JtaTransactionManager 하나만 등록돼야 함
- 단, 두 개 이상의 DB를 완전히 독립적으로 사용하는 경우는 두 개 이상 등록 할 수 있다.
- DataSource도 두 개 이상
- 트랜잭션 경계설정 전략
- 일반적 경계 : 서비스 계층 오브젝트의 메소드
- 경계설정방법
- 코드에 의한
- 스프링의 트랜잭션 매니저는 모두 PlatformTransactionManager를 구현하고 있음
- 현재 등록되어있는 트랜잭션 매니저 빈을 가져 올 수 있다면 트랜잭션 매니저의 종류에 상관없이 동일한 방식으로 트랜잭션을 제어하는 코드를 만들 수 있음
- PlatformTransactionManager를 직접써도 되지만 try/catch 블록을 써야 하는 번거로움 있음
- TransactionTemplate를 이용하면 편리
- 트랜잭션 기본 속성변경시 TransactionTemplate를 만들 때 TransactionDefinition 오브젝트를 만들어서 파라미터로 제공
- 구현체 : DataSourceTransactionManager, JtaTransactionManager
- 실제로 많이 사용되지는 않지만 의도적으로 트랜잭션을 만들고 종료시키거나 여러 번 트랜잭션을 거치는 상황을 만들어야 하는 경우 유용함
- 현재 트랜잭션 확인 : getTransaction()의 TransactionStatus 오브젝트를 활용
- AOP를 이용한 선언적 방법
- aop와 tx 네임스페이스
- aop와 tx 스키마의 태그 사용
- 어드바이스 : 트랜잭션 어드바이스
- pointcut : 대상선정, 인터페이스에 적용하는 것을 권장
- 서비스 게층의 메소드가 트랜잭션의 경계가 되는 것이 자연스러움
- @Transactional
- 설정파일에 명시적으로 포인트컷과 어드바이스를 정의하지 않음
- 타깃 인터페이스, 클래스, 메소드 등에 @Transactional을 지정
- 필요 설정 : <tx:annotation-driven>
- AOP 방식의 한계점
- 클라이언트가 타깃 오브젝트로 위장한 프록시의 메소드를 호출 했을 때만 프록시를 거치기 때문에 정상적으로 동작함
- 만약 타깃 오브젝트가 자신의 메소드를 호출 할 때는 프록시를 거치기 않기 때문에 정상적으로 처리 되지 않음
- 해결 방법
- AopContext.currentProxy()
- 프록시에서 제공하는 API를 호출
- 권장 안함
- AspenctJ AOP
- 트랜잭션 속성
- propagation
- 트랜잭션을 시작하거나 기존 트랜잭션에 참여하는 방법 결정
- 스프링에서 6가지를 지원하는데 모든 종류의 트랜잭션 매니저와 데이터 액세스 기술에서 다 지원하지 않으므로 주의
- 속성
- REQUIRED
- 모든 트랜잭션 매니저 지원
- 시작된 트랜잭션이 있으면 참여, 없으면 새로 시작
- SUPPORTS
- 시작된 트랜잭션이 있으면 참여, 없으면 없이 진행
- MANDATORY
- 시작된 트랜잭션이 있으면 참여, 없으면 예외
- REQUIRES_NEW
- 항상 새 트랜잭션
- 진행 중인 것이 있으면 그 것을 보류 시킴
- NOT_SUPPORTED
- 트랜잭션 사용 안함.
- 진행 중인 것은 보류
- NEVER
- 트랜잭션 사용 안함.
- 진행 중인 것이 있으면 예외
- NESTED
- 진행중인 것이 있으면 중첩 트랜잭션 시작
- 중첩된 것은 부모의 커밋 롤백에 영향을 받음
- 자신의 커밋과 롤백은 부모에 영향을 주지 않음
- JDBC 3.0 스펙의 저장포인트를 지원하는 드라이버와 DataSourceTransactionManager를 이용할 경우에 적용 가능
- 중첩 트랜잭션을 지원하는 일부 WAS의 JTA 트랜잭션 매니저를 이용할 때 적용 가능
- isolation
- 동시에 여러 트랜잭션이 진행될 때 트랜잭션의 작업 결과를 어떻게 노출 시킬 것인지
- 속성
- DEFAULT
- 데이터 액세스 기술 또는 db 드라이버의 디폴트 설정 따름:보통 DB 격리수준을 따르는 것이 일반적
- READ_UNCOMMITTED
- 커밋 되기 전의 데이터가 다른 트랜잭션에도 노출됨
- 성능 극대화
- READ_COMMITTED
- 실제로 많이 사용됨
- 다른 트랜잭션이 커밋하지 않은 정보를 읽을 수 없음
- 다른 트랜잭션이 읽은 로우를 다른 트랜잭션이 수정 할 수 있음
- REPEATABLE_READ
- 하나의 트랜잭션이 읽은 로우를 다른 트랜잭션이 수정하는 것을 막음
- 새로운 로우 추가는 제한 안함
- SERIALIZABLE
- 트랜잭션을 순차적으로 진행시켜야 할 경우
- 여러 트랜잭션이 동시가 같은 테이블의 정보를 액세스 하지 못함
- 성능 떨어짐
- timeout
- 트랜잭션의 제한 시간, 초단위
- 디폴트를 시스템의 제한시간
- read-only, readOnly
- 트랜잭션을 읽기 전용으로 만듬
- 일부 트랜잭션 매니저는 읽기 전용 속성을 무시하고 수정할 수 있으므로 주의
- rollback-for, rollbackFor, rolbackForClassName
- 선언적 트랜잭션에서 런타임 예외 발생시 롤백
- 예외가 없거나 체크 예외 발생시 커밋
- 이 동작 방식을 바꾸고자 할 때
- no-rollback-for, noRollbackFor, noRollbackForClassName
- 기본적으로 롤백 대상인 런타임 예외를 트랜잭션 커밋 대상으로 지정
- 트랜잭션 통합
- DataSourceTransactionManager
- JDBC, iBatis 두 가지 기술을 함께 사용 할 수 있음
- 항상 동일한 DataSource를 사용해야 함
- JtaTransactionManager
- JTA 서버 환경 구축, DataSource 구성이 필요
- 하나 이상의 DB 또는 JMS와 같은 트랜잭션이 지원되는 서비스를 통합해서 하나의 트랜잭션으로 관리하고자 할 때 반드시 필요
- JdbcTemplate 사용 권장
출처 : 토비의 스프링3.1의 트랙잭션 파트를 요약 정리하였음
반응형
Comments