Spring/Spring

[Spring][Data Access] 1-3. Transaction Manager: Synchronizing Resources with Transactions

noahkim_ 2024. 8. 11. 10:36

1. 트랜잭션 매니저와 리소스의 연관성

  • 트랜잭션 매니저는 특정 리소스와 연결되어 있음 (Database connection, Hibernate session)
  • 각각의 트랜잭션 매니저는 자신과 연결된 리소스를 자동으로 관리 및 사용 (생성 - 재사용 - 정리)

 

2. Transaction Synchronization

  • 리소스들이 트랜잭션의 시작과 종료 시점에 적절히 동작하도록 하는 매커니즘

 

트랜잭션 시작
  • 트랜잭션 컨텍스트 내에서 동기화됨

 

트랜잭션 종료
  • 커밋 or 롤백 -> 동기화 해제

 

3. High-level Synchronization Approach

Template-based API

@Repository
public class UserRepository {

    private final JdbcTemplate jdbcTemplate;

    public UserRepository(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public List<User> findAllUsers() {
        String sql = "SELECT * FROM users";
        return jdbcTemplate.query(sql, new UserRowMapper());
    }

    public void saveUser(User user) {
        String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
        jdbcTemplate.update(sql, user.getName(), user.getEmail());
    }

    private static class UserRowMapper implements RowMapper<User> {
        @Override
        public User mapRow(ResultSet rs, int rowNum) throws SQLException {
            User user = new User();
            user.setId(rs.getLong("id"));
            user.setName(rs.getString("name"));
            user.setEmail(rs.getString("email"));
            return user;
        }
    }
}
  • 명시적 코드 작성
  • 데이터 접근 작업을 자동으로 처리 (연결 - 쿼리 실행 - 예외 처리)
  • JdbcTemplate, HibernateTemplate
 

Transaction-aware Factory or Proxy

@Service
public class OrderService {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    public void placeOrder(Order order) {
        entityManager.persist(order);
        // 다른 비즈니스 로직...
    }
}
  • 트랜잭션에 의해 관리되는 리소스들을 트랜잭션 범위 내에서 자동으로 관리 (필요 시, 동기화 처리)

 

ORM API

  • Spring의 트랜잭션 관리 기능을 사용하여 ORM API가 트랜잭션 컨텍스트 내에 원활히 동작하도록 보장

 

4. Low-level Synchronization Approach

  • Spring의 유틸리티 클래스를 사용하여, 애플리케이션 코드가 직접 Native Persistence API의 리소스를 다루도록 하는 방식

 

DataSourceUtils

DataSourceUtils.getConnection(datasource)
  • 기존 트랜잭션이 이미 연결된 데이터베이스 연결이 있는 경우, 해당 연결을 반환
  • 기존 트랜잭션이 이미 연결된 데이터베이스 연결이 없는 경우, 새로운 연결 생성 및 현재 트랜잭션에 동기화

 

예외
  • Spring의 예외 처리 구조로 변환됨 (일관성)
  • SQLException을 CannotGetJdbcConnectionException으로 변환

 

EntityManagerFactoryUtils

SessionFactoryUtils

 

5. TransactionAwareDataSourceProxy

  • Spring의 DataSource Proxy
  • 트랜잭션의 데이터베이스 연결 관리 (트랜잭션 생성 시, 새로운 커넥션 생성)
  • 트랜잭션 경계 내 커넥션 공유 (동일한 데이터베이스 커넥션 재사용)
더보기
더보기
@Bean
public TransactionAwareDataSourceProxy transactionAwareDataSource(DataSource dataSource) {
    // 데이터 소스를 감싸는 프록시 생성
    return new TransactionAwareDataSourceProxy(dataSource);
}

 

 

출처