FireDrago

[Spring] 트랜잭션과 스프링 본문

프로그래밍/Spring

[Spring] 트랜잭션과 스프링

화이용 2024. 2. 28. 11:14

트랜잭션을 스프링에서 지원하는 기능을 사용하여 단계적으로 구현해보자

 

<트랜잭션 매니저>

<트랜잭션 추상화>

트랜잭션은 어떤 데이터베이스 연결 기술을 쓰느냐에 따라 달라질 수 있다. 

JDBC , JPA 등등 기술마다 트랜잭션을 구현하는 방법이 다르다.

이 문제를 해결하기 위해 스프링은 트랜잭션 매니저 (PlatformTransactionManager) 인터페이스를 제공한다.

 

<트랜잭션 동기화>

트랜잭션 매니저 인터페이스는 트랜잭션의 추상화 뿐만아니라, 트랜잭션 기능 구현을 위한

커넥션 유지 기능도 함께 제공한다. 즉 commit / rollback 되기 전까지 쓰레드 풀에 커넥션을 보관하고

리포지토리에서 동일한 커넥션을 사용 할 수 있도록 지원한다. 코드를 통해 확인해보자

 

transactionManager.getTransaction (설정 객체)  를 통해 트랜잭션 상태 객체를 생성한다.

이후 비지니스 로직이 실행되고, commit / rollback 메서드를 호출할때 상태 객체를 전달한다.

 

트랜잭션 매니저는 commit 과 rollback 이후 트랜잭션 동기화 매니저에 보관된 커넥션 객체를 가져온다.

커넥션 객체의 commit / rollback 을 실행한뒤,

커넥션 setAutoCommit(false) 를 통해 커넥션 풀에 반환하기 위한 리소스 정리를한다.

마지막으로 커넥션을 종료하거나, 커넥션 풀에 반납한다.

 

Repository 객체의 연결과 종료 메서드

리포지토리 객체에서는 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