ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 리액티브 프로그래밍에서의 트랜잭션 관리: @Transactional vs TransactionalOperator
    카테고리 없음 2021. 8. 1. 21:34

    리액티브 프로그래밍에서 비동기 데이터 흐름에서 트랜잭션을 안전하게 관리하는 방법에대해 알아보자. R2DBC등의리액티브 데이터베이스 연동에서 트랜잭션 관리는 중요하다. 그런데 MVC 에서 주로 썼던 @Transactional 어노테이션을 그대로 사용해도 될까?  TransactionalOperator 클래스는 무엇인지 알아보고 각 접근법의 적합성에 대해서 알아보자.

     

     

    @Transactional 어노테이션

    @Transactional 어노테이션은 전통적인 동기적 트랜잭션 관리에서 널리 사용된다. 이 어노테이션은 메서드의 시작과 끝에서 트랜잭션을 관리하며, 예외 발생 시 트랜잭션을 롤백한다. 그러나 리액티브 프로그래밍 환경에서는 몇 가지 제한이 있다.

    1. 외부 호출에 의존: @Transactional은 주로 외부 클래스에서 메서드를 호출할 때 트랜잭션을 관리한다. 내부 메서드 호출에서는 트랜잭션이 제대로 적용되지 않을 수 있다.
    2. 트랜잭션 경계 불명확: 리액티브 체이닝에서 트랜잭션 경계가 명확하지 않아 트랜잭션의 일관성을 보장하기 어렵다.

     

    @Transactional 어노테이션을 사용하는 경우, 비동기적으로 실행되는 리액티브 스트림의 특성상 트랜잭션의 일관성이 보장되지 않을 수 있다. 이는 @Transactional이 전통적인 동기적 트랜잭션 경계를 가정하기 때문이다.

     

    @Transactional

    1. 전통적인 동기적 트랜잭션 관리: @Transactional은 주로 전통적인 동기적 프로그래밍 환경에서 사용. 스프링은 메서드 진입 시 트랜잭션을 시작하고, 메서드가 종료되면 트랜잭션을 커밋하거나 롤백함
    2. AOP 기반: @Transactional은 Aspect-Oriented Programming(AOP) 개념을 사용하여 메서드 호출의 앞뒤에 트랜잭션 관리 로직을 삽입한다. 이는 메서드가 호출되기 전에 트랜잭션을 시작하고, 메서드가 정상적으로 종료되면 커밋하며, 예외가 발생하면 롤백하는 방식이다.
    3. 동기적 코드에 적합: @Transactional은 주로 동기적 트랜잭션 경계를 정의하기 때문에, 리액티브(비동기적) 프로그램에서는 트랜잭션 일관성을 보장하기 어려울 수 있다. 리액티브 스트림의 비동기 특성으로 인해 트랜잭션 경계가 명확히 정의되지 않을 수 있기 때문.

    따라서, 리액티브 프로그램에서 트랜잭션의 일관성을 보장하려면 TransactionOperator를 사용하는 것이 더 적합하다.TransactionOperator는 리액티브 스트림 내에서 트랜잭션의 시작과 끝을 명확히 정의할 수 있으며, 데이터베이스 트랜잭션의 커밋 또는 롤백을 정확하게 제어할 수 있다.

     

     

    TransactionalOperator 클래스

    TransactionalOperator는 리액티브 환경에서 트랜잭션을 관리하기 위해 설계된 도구이다. 리액티브 스트림의 트랜잭션 경계를 명확히 설정하고, 비동기 작업의 트랜잭션 일관성을 보장한다.

    1. 리액티브 프로그래밍에 최적화: TransactionalOperator는 리액티브 스트림의 특성을 고려하여 트랜잭션 상태를 관리한다. 이는 리액티브 스트림 내의 모든 작업이 하나의 트랜잭션으로 처리되도록 보장한다.
    2. 유연한 제어: 개발자가 트랜잭션 범위를 명시적으로 설정하고 관리할 수 있으며, 필요에 따라 트랜잭션 경계를 조정할 수 있다.

     

    .as(transactionalOperator::transactional)

    1. 리액티브 트랜잭션 관리: .as(transactionalOperator::transactional)은 리액티브 프로그래밍 환경에서 사용된다. 리액티브 스트림에서 트랜잭션을 시작하고 완료하는 것을 제어한다.
    2. 리액티브 체이닝 내 트랜잭션 경계 설정: 이 방법은 리액티브 체이닝 내에서 트랜잭션의 범위를 명확히 설정할 수 있습다. .as(transactionalOperator::transactional)를 사용하면 특정 리액티브 스트림의 시작과 끝에서 트랜잭션을 명확히 정의할 수 있으며, 스트림 내에서 발생하는 모든 작업이 하나의 트랜잭션으로 처리된다.
    3. 비동기 작업에 적합: TransactionOperator는 리액티브 체이닝의 특성을 반영하여 비동기적으로 트랜잭션을 관리한다. 이는 트랜잭션의 시작과 끝을 리액티브 스트림 내에서 자연스럽게 관리할 수 있게 해준다.

     

     

    리액티브 환경에서 트랜잭션의 일관성을 보장하려면 TransactionalOperator를 사용하는 것이 더 적합하다. @Transactional 어노테이션은 동기적 작업에 유용하지만, 리액티브 체이닝에서는 제약이 있다. 이를 통해 리액티브 프로그래밍에서도 안정적인 트랜잭션 관리가 가능하다.

     

    출처:

    https://www.vinsguru.com/spring-data-r2dbc-transaction/

     

    Spring Data R2DBC Transaction | Vinsguru

    Learn how we could achieve DB transaction with Spring Data R2DBC Transaction operator & also with @Transactional.

    www.vinsguru.com

    https://spring.io/blog/2019/05/16/reactive-transactions-with-spring

     

    Reactive Transactions with Spring

    Back in 2016, our reactive journey started with Spring Framework 5 accompanied by a couple of reactive integrations. Throughout our journey, other projects joined the reactive movement. With R2DBC, we now also provide a reactive integration for SQL databas

    spring.io

     

Designed by Tistory.