복붙노트

[SPRING] Spring 트랜잭션 관리자와 다중 쓰레드

SPRING

Spring 트랜잭션 관리자와 다중 쓰레드

호출 가능한 인터페이스를 사용하여 serviceImpl에 다중 쓰레드 프로그램을 작성 중입니다. 스프링 트랜잭션 관리자를 사용하고 있습니다. DB에서 업데이트 작업을 수행하면 성공적으로 실행됩니다.하지만 업데이트 된 데이터는 DB에 반영되지 않습니다. 그러나 멀티 쓰레드없이 프로그램을 실행하면 DB에서 업데이트되었습니다.

이것은 나의 구성이다.

<tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="*" />
            <tx:method name="find*" propagation="NOT_SUPPORTED" />
            <tx:method name="get*" propagation="NOT_SUPPORTED" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="serviceOperation" expression="execution(* *..*ServiceImpl.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
    </aop:config>
    <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

트랜잭션 관리자를위한 또 다른 접근 방식으로 바꿀 수 있습니다.이 접근 방식이 멀티 스레딩을 지원하는지 여부를 확인하고 싶습니다. 그래서 내 질문은 스프링 트랜잭션 관리자는 멀티 스레딩을 지원합니까 (주석 또는 XML을 선언하는 것만으로) 필자의 경우 업데이트 된 데이터가 DB에 반영되지 않는 이유는 무엇입니까? 가장 좋은 대안은 무엇일까요?

해결법

  1. ==============================

    1.Spring에서 사용하는 트랜잭션 컨텍스트는 스레드 로컬 변수에 저장됩니다. 따라서 새로운 스레드를 시작하거나 호출 가능 객체를 사용하여 다른 스레드에서 코드를 실행하면이 코드는 Spring 트랜잭션 측면에서 시작된 트랜잭션의 일부가되지 않습니다. 이것이 귀하의 데이터가 데이터베이스에 나타나지 않는 이유입니다.

    Spring에서 사용하는 트랜잭션 컨텍스트는 스레드 로컬 변수에 저장됩니다. 따라서 새로운 스레드를 시작하거나 호출 가능 객체를 사용하여 다른 스레드에서 코드를 실행하면이 코드는 Spring 트랜잭션 측면에서 시작된 트랜잭션의 일부가되지 않습니다. 이것이 귀하의 데이터가 데이터베이스에 나타나지 않는 이유입니다.

  2. ==============================

    2.멀티 스레딩을 어떻게 수행하고 있는지 보여주기 때문에 내가 한 일만 추측 할 수 있습니다.

    멀티 스레딩을 어떻게 수행하고 있는지 보여주기 때문에 내가 한 일만 추측 할 수 있습니다.

    YourService.doSomething ()에는 createThreads가 있습니다. 각 스레드에 대해 DB 관련 작업을 수행하고 있습니다. 그게 맞습니까?

    다른 대답으로 설명 된 것처럼 트랜잭션 컨텍스트는 스레드 로컬 방식으로 저장됩니다. 따라서 스레드의 논리에는 트랜잭션과 아무 관련이 없습니다. 당신이 이것을 확인할 수있는 한 가지는 doSomething ()에서 스레드의 논리와 별개로 일부 DB 작업을 수행한다는 것입니다. 스레드의 작업이 손실되는 동안 doSomething ()에서 수행 한 db 작업이 커밋됨을 알 수 있습니다.

    합리적으로 해결할 수있는 방법 중 하나는 일반적으로 작업 단위 역할을하는 응용 프로그램 서비스 계층을 사용하므로 서비스 경계와 비슷한 트랜잭션 경계가 있습니다. 스레드는 서비스에서 제공하는 작업을 호출해야합니다. 물론 그들은 모두 다른 거래가 될 것입니다.

    그것들을 모두 하나의 트랜잭션으로 원하면 다른 방법은 개별 스레드가 DB 작업을 수행하는 대신 스레드가 이제는 많은 작업을 수행하고 결과를 원래 스레드 (예 : 생산자 - 고객 대기열)에 게시합니다. 원래 스레드는 결과를 수집하고 DB 조치를 수행해야합니다.

    개인적으로 나는 다른 스레드 주위에 트랜잭션 컨텍스트를 수동으로 전달하는 것을 피하려고합니다. 이것은 단순히 선언적 트랜잭션이라는 전체 개념을 망칠뿐입니다.

  3. ==============================

    3.Spring에서 고유 한 TransactionSynchronizationManager를 구현하고 삽입하려고 할 수 있습니다. ThreadLocal 대신 InmheritableThreadLocal과 같은 것을 사용하십시오.

    Spring에서 고유 한 TransactionSynchronizationManager를 구현하고 삽입하려고 할 수 있습니다. ThreadLocal 대신 InmheritableThreadLocal과 같은 것을 사용하십시오.

  4. from https://stackoverflow.com/questions/16835974/spring-transaction-manager-and-multithreading by cc-by-sa and MIT license