FireDrago
[Spring] 트랜잭션과 스프링 본문
트랜잭션을 스프링에서 지원하는 기능을 사용하여 단계적으로 구현해보자
<트랜잭션 매니저>



<트랜잭션 추상화>
트랜잭션은 어떤 데이터베이스 연결 기술을 쓰느냐에 따라 달라질 수 있다.
JDBC , JPA 등등 기술마다 트랜잭션을 구현하는 방법이 다르다.
이 문제를 해결하기 위해 스프링은 트랜잭션 매니저 (PlatformTransactionManager) 인터페이스를 제공한다.
<트랜잭션 동기화>
트랜잭션 매니저 인터페이스는 트랜잭션의 추상화 뿐만아니라, 트랜잭션 기능 구현을 위한
커넥션 유지 기능도 함께 제공한다. 즉 commit / rollback 되기 전까지 쓰레드 풀에 커넥션을 보관하고
리포지토리에서 동일한 커넥션을 사용 할 수 있도록 지원한다. 코드를 통해 확인해보자

transactionManager.getTransaction (설정 객체) 를 통해 트랜잭션 상태 객체를 생성한다.
이후 비지니스 로직이 실행되고, commit / rollback 메서드를 호출할때 상태 객체를 전달한다.
트랜잭션 매니저는 commit 과 rollback 이후 트랜잭션 동기화 매니저에 보관된 커넥션 객체를 가져온다.
커넥션 객체의 commit / rollback 을 실행한뒤,
커넥션 setAutoCommit(false) 를 통해 커넥션 풀에 반환하기 위한 리소스 정리를한다.
마지막으로 커넥션을 종료하거나, 커넥션 풀에 반납한다.

리포지토리 객체에서는 DataSourceUtils.getConnection(dataSource) 사용하여 트랜잭션 동기화 매니저가 관리하는
커넥션이 있을경우 가져오고, 없으면 커넥션을 생성한다.
DataSourceUtils.releaseConnection(con, dataSource) 는 트랜잭션 동기화 매니저가 관리하는 커넥션이 있으면,
커넥션을 유지한다. 관리하지 않으면 커넥션을 종료한다.
이 두 기능을 통해 리포지토리의 각 메서드들은 매번 커넥션 객체를 파라미터로 전달 받을 필요가 없다.

DI 를 통해 트랜잭션 매니저를 주입할때는 DataSource 객체를 함께 주입한다.
<트랜잭션 AOP>

스프링에서 제공하는 트랜잭션 AOP 기능은 서비스 객체에서 비지니스 로직과 트랜잭션 로직을 분리할 수 있게 해준다
트랜잭션 매니저를 서비스 객체에서 직접 의존하는 것이 아니라, 프록시 객체가 트랜잭션 매니저와 트랜잭션 로직을
담당하고, 서비스를 호출하는 형태로 작동한다.
또한 스프링부트는 트랜잭션 매니저와 데이터 소스 객체를 자동으로 빈 생성한다.
사용자가 직접 트랜잭션 매니저와 데이터 소스 객체를 생성하고 관리할 필요가 없는 것이다. 코드로 살펴보자




서비스 객체에서는 @Transactional 애너테이션을 붙임으로서 자동으로 트랜잭션 AOP 기능이 실행된다.
서비스 객체에서 트랜잭션을 담당하는 코드들이 완전히 분리되었다.
오른쪽 코드는 서비스 객체의 테스트 코드중 빈을 생성하는 내부 객체 코드이다.
@TestConfiguration 애너테이션과 @Bean 을 통해 서비스 객체와 리포지토리 객체를 생성하고 있다.
그런데 DataSource 는 서비스 객체와 리포지토리 객체를 생성하는데 필요하니 멤버변수로 등록한 것은
알겠는데 TransactionManager, DataSource 객체는 빈으로 등록하지 않았다.
스프링 부트가 두 객체를 자동으로 등록해주기 때문이다.
스프링 부트는 커넥션풀을 제공하는 HikariDataSource 를 자동으로 빈으로 등록하고,
JPA, JDBC 를 판단하여 TransactionManager 빈을 생성한다. (둘다 쓰면 JPA)
그래서 DataSource 를 빈 생성 없이 주입받을 수 있는 것이다.
DataSource 객체를 생성할때는 application.properties에 위와 같은 설정값을 바탕으로 객체가 생성된다.
'프로그래밍 > Spring' 카테고리의 다른 글
| [Spring] DB 연결을 테스트 하기 (0) | 2024.03.06 |
|---|---|
| [Spring] DB 예외처리 (0) | 2024.03.02 |
| [Spring] 파일업로드 (0) | 2024.02.22 |
| [Spring] 스프링 타입 컨버터와 포매터 (0) | 2024.02.21 |
| [Spring] 스프링 API 예외처리 (0) | 2024.02.20 |
