1. 트랜잭션이란? (ACID)
- 하나의 논리적 작업 단위로 수행되는 일련의 작업
- 일련의 작업이 모두 하나의 논리적 작업으로 취급되기 때문에 논리적 작업을 취소하면, 그 내부에 포함된 일련의 작업들이 모두 취소된다.
2. 테스트코드에서의 @Transactional 사용
- 역할 : DB와 관련된 테스트코드를 작성하면 테스트메서드에 @Transactional을 사용하여 테스트 메서드가 종료될 때 생성된 DB 커밋을 rollback한다.
- @Transactional 을 사용하지 않고 @Service테스트를 실행하면?
- 테스트 메서드 내부에서 사용했던 데이터들이 남게되어 실제 서비스에 영향을 미칠 수 있어 지워야할 필요가 있다.
- DB에 반영하고 싶다면 @Rollback(false)
- auto_increment나 sequence 등에 의해 증가된 값은 롤백이 되지 않는다.
- 별도의 데이터베이스로 연결을 하거나 또는 H2와 같은 휘발성(인메모리) 데이터베이스를 사용하여 해결
3. 프로덕션 코드에서의 @Transactional 사용
3-1. 일반적으로 비지니스 로직을 담고 있는 서비스 계층의 메소드와 결합시키는 것이 좋음
- 데이터 저장 계층으로부터 읽어온 데이터를 사용하기 때문
- 데이터를 사용하고 변경하는 등의 작업을 하는 곳이기 때문
3-2. 읽기 전용 트랜잭션의 공통화 (SELECT) : 사용권장!
- @Transactional(readOnly = true)
- SELECT 문에 대해서만 기능을 지원
- 스냅샷을 통해 데이터 일관성을 보장
- CUD 작업이 동작하지 않아(스냅샷을 저장하기에) 변경 감지등의 작업을 수행하지 않음으로 성능이 향상
- final을 두어 객체의 신뢰성을 보장하는 것과 비슷하다!
3-3. 그렇다면 그 외의 경우? CUD (Create, Update, Delete)
- 단일 객체의 쓰기 : 일반적으로 쓰이는 트랜잭션의 의미는 아니다(다중 연상을 하나의 실행단위로 묶는 매커니즘이기 때문)
- 과도한 트랜잭션 처리는 성능에 불리하다.
- 다중 객체 트랜잭션
- 성능 vs 무결성/관리비용 : 둘 중 무엇이 더 중요한지 판단하여 적절한 격리 수준을 적용하는 것이 중요하다!
- 트랜잭션은 꼭 필요한 최소의 코드에 적용하는 것이 좋다. (https://elky84.github.io/2020/02/07/db_transaction/)
4. 결론
- SELECT쿼리인 경우, @Transactional(readOnly = true)를 사용하면 다른 트랜잭션 사용과 다르게 성능이 향상되기에 사용을 권장한다.
- 무결성/관리비용의 중요성이 낮은 서비스는 트랜잭션을 적용하지 않는다. 적절한 트랜잭션 적용이 필요하다. -> 성능이슈(Transaction은 많은 Cost를 발생시킨다)
'공부 > Spring' 카테고리의 다른 글
[Spring] DTO의 사용 범위 (0) | 2022.05.07 |
---|---|
[Java] @Transaction(readOnly=true)을 사용하면 성능이 향상되는 이유 (4) | 2022.05.07 |
[Spring] DB연동 없이 DB테스트 수행하기 (0) | 2022.04.29 |
[Spring] 의존성 주입 3가지 방법(생성자 주입을 사용하자) (0) | 2022.04.26 |
[Spring](스프링 핵심 원리 - 기본편) 스프링 핵심 원리 이해1 - 예제 만들기 (0) | 2022.04.19 |
댓글