Spring/Spring

[Spring][Data Access] 1-4. Transaction Manager: Declarative Transaction Management - Understanding the Spring Framework’s Declarative Transaction Implementation (1)

noahkim_ 2024. 8. 11. 11:12

1. Declarative Transaction Management with AOP Proxies

@Transactional

  • 해당 에노테이션을 메소드 또는 클래스에 사용하여 적용하는 방식

 

Transaction Metadata
  • 트랜잭션 관리에 필요한 정보를 메타데이터를 통해 제공 (XML or Annotation)
  • 전파 수준, 롤백 규칙 (예외 클래스), 읽기 전용
더보기
@Service
public class ProductService {

    // 기본 트랜잭션 설정: REQUIRED 전파 수준, 기본 격리 수준
    @Transactional
    public void addProduct(Product product) {
        // 트랜잭션이 시작됩니다.
        saveProduct(product);
        updateInventory(product);
        // 트랜잭션이 정상적으로 완료되면 커밋됩니다.
    }

    // 트랜잭션을 새로운 트랜잭션으로 시작 (REQUIRES_NEW)
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveProduct(Product product) {
        // 새로운 트랜잭션이 시작됩니다.
        // 데이터베이스에 제품 저장
    }

    // 특정 예외 발생 시 트랜잭션 롤백 (예: OutOfStockException)
    @Transactional(rollbackFor = OutOfStockException.class)
    public void updateInventory(Product product) throws OutOfStockException {
        // 재고 업데이트
        if (product.getStock() <= 0) {
            throw new OutOfStockException("Out of stock");
        }
    }

    // 읽기 전용 트랜잭션
    @Transactional(readOnly = true)
    public Product findProductById(Long id) {
        // 데이터베이스에서 제품 조회 (읽기 전용)
        return productRepository.findById(id).orElse(null);
    }
}

 

AOP Proxy

  • 메서드 호출 전 후에 트랜잭션 관련 코드를 삽입
  • Spring은 해당 메서드의 트랜잭션 관리를 담당

 

TransactionInterceptor
  • 트랜잭션 경계 설정
  • 메서드 호출 시작: 트랜잭션 시작
  • 메서드 호출 완료: 트랜잭션 커밋 (예외 시, 롤백)

 

더보기

등록

@Component
public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Pre Handle method - Intercepting the Request");

        // true를 반환하면 컨트롤러로 요청이 전달됩니다.
        // false를 반환하면 요청이 중단됩니다.
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // 컨트롤러에서 요청 처리 후, 뷰 렌더링 전 실행될 로직
        System.out.println("Post Handle method - Request processing is done");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // 뷰 렌더링 후에 실행될 로직
        System.out.println("After Completion method - Request is complete");
    }
}
더보기

설정

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private CustomInterceptor customInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 인터셉터 등록
        registry.addInterceptor(customInterceptor)
                .addPathPatterns("/api/**")  // 특정 경로에만 인터셉터 적용
                .excludePathPatterns("/api/public/**");  // 특정 경로는 인터셉터에서 제외
    }
}

 

 

출처