개념
들어가기에 앞서
트랜잭션은 Spring의 대표적인 AOP 기술 중 하나입니다. 다른 프레임워크에선 이 @Transactional 기술을 부러워 하는 경우도 있습니다.
왜 그럴까요?
트랜잭션을 사용하지 않은 코드
public void saveUser(User user) {
Connection connection = null;
try {
// 데이터베이스 커넥션을 얻음
connection = dataSource.getConnection();
// 트랜잭션 시작
connection.setAutoCommit(false);
// 사용자 저장 로직 실행
PreparedStatement statement = connection.prepareStatement(
"INSERT INTO users (username, email) VALUES (?, ?)"
);
statement.setString(1, user.getUsername());
statement.setString(2, user.getEmail());
statement.executeUpdate();
// 트랜잭션 커밋
connection.commit();
} catch (SQLException e) {
if (connection != null) {
try {
// 예외 발생 시 롤백
connection.rollback();
} catch (SQLException rollbackEx) {
rollbackEx.printStackTrace();
}
}
e.printStackTrace();
} finally {
if (connection != null) {
try {
// 커넥션 닫기
connection.close();
} catch (SQLException closeEx) {
closeEx.printStackTrace();
}
}
}
}
트랜잭션을 사용한 코드
@Transactional
public void saveUser(User user) {
userRepository.save(user);
}
@Transactional AOP 하나로 코드를 이렇게 줄일 수 있습니다.
@Transactional 의 숨겨진 기술: CGLib & JDK Proxy
- 직접 코드 수정 없이 트랜잭션 적용
- Spring 은 애플리케이션 코드에 직접적으로 트랜잭션 관련 로직(beginTransaction(), commit(), rollback()) 을 추가하지 않습니다. 대신, 프록시(Proxy) 객체를 생성하여 해당 로직을 자동으로 추가하여 실행합니다.
- Spring IoC Container 의 역할위의 예시로 UserService 클래스에 @Transactional 이 선언되어 있으면 UserService 대신 UserServiceProxy 라는 프록시 객체가 생성됩니다.
- Spring 은 @Transactional 이 선언된 클래스나 메서드를 감싸는 프록시 객체를 IoC 컨테이너에서 생성합니다.
- CGLib과 JDK Dynamic Proxy의 사용JDK Dynamic Proxy: 인터페이스를 기반으로 프록시 객체를 생성.
- CGLib: 상속을 통해 프록시 객체를 생성. (클래스 기반 프록시)
Spring은 기본적으로 인터페이스가 있을 경우 JDK Dynamic Proxy를, 인터페이스가 없을 경우 CGLib을 사용합니다.
- 트랜잭션 코드가 프록시 위에서 동작이렇게 하면 실제 메서드 코드는 변경하지 않아도 트랜잭션이 적용된 것처럼 동작합니다.
- 프록시 객체가 실제 메서드를 호출하기 전에 트랜잭션과 관련된 로직(시작, 커밋, 롤백)을 처리합니다.
Transactional Manager
결국 Proxy도 적용했고 Proxy가 Transaction도 관리하고 있습니다.
하지만 Proxy 가 Transaction 의 상태(begin, commit, rollback)를 스스로 알아서 관리하기엔 한계가 있습니다.
따라서 트랜잭션의 실제 상태를 관리하는 역할은 Transation Manager 에게 위임됩니다.
- Spring에서 제공하는 PlatformTransactionManager대표적인 구현체로는 DataSourceTransactionManager가 있습니다.
- Spring은 다양한 구현체를 제공하는 PlatformTransactionManager 인터페이스를 통해 트랜잭션을 관리합니다.
- Transaction Manager의 역할
- 트랜잭션 커밋(doCommit 메서드).
- 트랜잭션 롤백 관리.
- 트랜잭션 시작(doBegin 메서드).
Spring Config 에서 Transaction Manager 를 등록하는 예는 다음과 같습니다.
@Bean
public DataSource dataSource() {
return new MysqlDataSource(); // 데이터베이스 연결
}
@Bean
public PlatformTransactionManager txManager() {
return new DataSourceTransactionManager(dataSource()); // 트랜잭션 관리
}
'CS' 카테고리의 다른 글
RAG란 무엇일까? (0) | 2025.02.01 |
---|---|
Service 끼리 의존 하는 것에 대하여 (0) | 2025.01.14 |