[1] Transactional
(1) TransactionManager 트랜잭션 매니저
DAO의 메서드는 개별 Connection 을 사용하기 때문에
성공해서 커밋이 되거나 실패하여 롤백이 되었을때
트랜잭션 관리를 할수 있고 그래서 트랜잭션 매니저가 TransactionManager가 필요하다
AOP를 이용한 핵심기능과 부가기능을 분리한다
(2) 트랜잭션 매니저 등록방법
1. 코드 직접작성
2. 빈으로 등록 (<tx:annotation-driven> @Transitional
(3) @Transactional 정의
모든 메서드에 적용가능하도록 클래스나 인터페이스에 붙일수 있다
(4) @Transitional 속성
propagation | Tx의 경게 boundary를 설정하는 방법을 지정한다 |
isolation | Tx의 isolation level을 지정한다 DB설정 DEFAULT , READ_UNCOMMITTED, READ_COMMITTED , 디폴트 REPEATABLE_READ , SERIALIZABLE |
readOnly | Tx가 데이터를 읽기만 한다 true로 지정하면 성능이 향상된다 |
rollbackFor | 지정된 예외가 발생하면 Tx를 rollback 한다 RuntimeException과 Error는 자동으로 rollback 한다 |
noRollbackFor | 지정된 예외가 발생해도 Tx가 rollback 하지 않는다 |
timeout | 지정된 시간 내에 Tx가 종료되지 않으면 강제로 종료한다 |
(5) propagation 속성 값
REQUIRED | Tx가 진행중이면 참여하고 없으면 new Tx를 시작한다 (디폴트) |
REQUIRES_NEW | Tx가 진행중이건 아니건 new Tx를 시작한다 Tx 안에 다른 Tx를 생성하는 것이다 = 서로 다른 트랜잭션 |
NESTED | Tx가 진행중이면 Tx의 내부에서 Tx가 실행한다 Tx 안에 서브 Tx(save point)를 생성하는 것이다 = 같은 트랜잭션 |
MANDATORY | 반드시 진행중인 Tx 내에서만 실행가능하다. 아니면 예외 발생 |
SUPPORTS | Tx가 진행중이건 아니건 상관없이 실행한다 |
NOT_SUPPORTED | Tx없이 처리한다. Tx가 진행중이면 잠시 중단된다 (suspend) |
NEVER | Tx없이 처리한다. Tx가 진행중이면 예외가 발생한다 |
[2] TransactionManager 수동등록
(1) DB 생성
(2) DAO 생성 : @ Repository
(2) JUnit 테스트 + 트랜잭션 매니저 생성
(3) 실행
트랜잭션 매니저 생성전에는 트랜잭션2번이 오류로 인해 트랜잭션1만 들어갔는데
트랜잭션 매니저 생성후에는 트랜잭션2번의 오류로 인해 트랜잭션1도 안들어간다
정상값이 입력된다면 트랜잭션 매니저가 정상적으로 실행되고
conn은 같은 값으로 나온다
[3] TransactionManager 빈 등록
(1)TransactionManager 빈등록
root-context.xml 파일에 빈을 등록한다
(2) @Autowired 등록
출력 결과 똑같음
[4] @Transactional의 구조
(1) REQUIRED
의미 : Tx가 진행중이면 참여하고 없으면 new Tx를 시작한다 (디폴트)
같은 트랜잭션 내에서 수행되기 때문에 어느위치로든 Rollback이 가능하다
(2) REQUIRES_NEW
Tx가 진행중이건 아니건 new Tx를 시작한다
Tx 안에 다른 Tx를 생성하는 것이다 = 서로 다른 트랜잭션
다른 트랜잭션 내에서 수행되기 때문에
A1과 A2는 같은 트랜잭션에 있기 때문에 서로의 관계에서는 rollback이 가능하나
A2에서 B1, B2에 rollback 할수 없다
또한
Tx1 트랜잭션에서 A2에서 A1으로 rollback 했을때
B1-B2가 진행된 트랜잭션Tx2는 정상작동이 유지되며, 같이 rollback 되지 않는다
(3) rollbackFor = Exception.class
데이터베이스 A1 테이블에 값을 넣고 문제가 있으면 롤백하게끔
데이터베이스 B1 테이블에 값을 넣고 문제가 있으면 롤백하게끔
설정했다.
(롤백 설정 : rollbackFor = Exception.class)
정상적으로 실행된다면 데이터베이스에 저장이 된다
insertA1withTx()와 insertB1WithTx()를 각각의 클래스로 나눠야한다
'🌈 백엔드 > 스프링 프레임워크' 카테고리의 다른 글
스프링_MyBatis (0) | 2023.09.23 |
---|---|
스프링_ 데이터 객체 DAO + 트랜잭션 서비스 (0) | 2023.09.10 |
스프링_테스트_JUnit 실행 (0) | 2023.09.07 |
스프링_ 시스템 프로퍼티 환경설정 (0) | 2023.09.06 |
BeansFactory & AppicationContext (0) | 2023.09.04 |