깔끔하게 정리된 코드로 트랜잭션 경계를 관리하기 위해 스프링이 제공하는 방법

Connection 파라미터 제거

Connection을 파라미터로 직접 전달하는 문제를 해결해보자.

upgradeLevels() 메서드가 트랜잭션 경계 설정을 해야 한다는 사실은 피할 수 없다.

  1. Connection 의 commit() 을 호출해서 트랜잭션을 완료한다.
  2. 트랜잭션 저장소가 더이상 Connection 오브젝트를 저장하지 않도록 제거한다.

어느 작업중에라도 예외 상황 발생 시 UserService 는 Connection**.rollback()** 을 호출하고 Connection 오브젝트는 제거한다.

<aside> 📌

트랜잭션 동기화 저장소는 작업 스레드마다 독립적으로 Connectino 오브젝트를 저장하고 관리한다. 고로 다중 사용자를 처리하는 서버의 멀티스레드 환경에서 충돌날 일은 없다.

</aside>

결과

  1. 파라미터를 통해 일일이 Connection 오브젝트를 전달할 필요가 없어진다.
  2. 트랜잭션 경계 설정이 필요한 메서드에서만 Connection 을 다룬다.
  3. UserDao 인터페이스에서 일일이 JDBC 인터페이스인 Connection 을 사용한다고 노출할 필요가 없다.

트랜잭션 동기화 적용

멀티스레드 환경에서도 안전한 트랜잭션 동기화 방법 구현은 기술적으로 어려운 일이다.

→ 스프링은 JdbcTemplate 과 더불어 트랜잭션 동기화 기능을 지원하는 유틸리티 메서드를 제공한다.

public class UserService {

  private DataSource dataSource;
  public void setDataSource(DataSource dataSource){
    this.dataSource = dataSource;
  }
// UserService.class
public void upgradeLevels(){
    **TransactionSynchronizationManager.initSynchronization();;**
    Connection c = **DataSourceUtils.getConnection(dataSource);**
    c.setAutoCommit(false);