복붙노트

[SPRING] Spring 3.x - @Async 메서드는 작업 실행자에 의해 동시에 호출되지 않습니다.

SPRING

Spring 3.x - @Async 메서드는 작업 실행자에 의해 동시에 호출되지 않습니다.

내 Service 클래스에서 동시 메서드 호출을 구현하려고합니다.

내 서비스 클래스에서 @Async로 주석 처리 된 일부 메소드가 있고이 메소드를 모두 동시에 호출하려고합니다. 그러나 메소드는 순차적으로 실행됩니다.

이것은 내 서비스 클래스 (더미)입니다.

@Service public class TestService {

public SomeDataType getSOmeDataType() {
        try {
            List<DataType> a = retrieveDataA().get();
            List<DataType> b = retrieveDataB().get();
            List<DataType> c = retrieveDataC().get();
            List<DataType> d = retrieveDataD().get();
            List<DataType> e = retrieveDataE().get();           
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        catch (ExecutionException e) {
            e.printStackTrace();
        }
        return referralDetailsReferenceData;
    }

@Async 
    private Future<List<DataType>> retrieveDataA() {
        //method logic
    }

@Async 
    private Future<List<DataType>> retrieveDataB() {
        //method logic
    }

@Async 
    private Future<List<DataType>> retrieveDataC() {
        //method logic
    }

@Async 
    private Future<List<DataType>> retrieveDataD() {
        //method logic
    }

@Async 
    private Future<List<DataType>> retrieveDataE() {
        //method logic
    }

이것은 내 봄 설정 :

<bean id="executorService" class="java.util.concurrent.Executors" factory-method="newFixedThreadPool">
    <constructor-arg value="10" />
</bean>

<task:executor id="threadPoolTaskExecutor" pool-size="10" />

<task:annotation-driven executor="executorService" />

"getSomeDataType"이 실행되면 메서드가 순차적으로 호출됩니다.

나는 @Async와 Spring에서의 동시 실행에 익숙하지 않아, 어리석은 짓을하고 있다고 확신한다. 그러나 나는 그것을 알아낼 수 없다.

모든 제안은 높이 평가됩니다.

해결법

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

    1.문제는 내부적으로 메소드를 호출하여 프록시가되지 않는다는 것입니다. @Async가 작동하려면 응용 프로그램 컨텍스트에서 개체를 검색하고 검색된 복사본의 메서드를 호출해야합니다. 내부적으로 호출하면 작동하지 않습니다.

    문제는 내부적으로 메소드를 호출하여 프록시가되지 않는다는 것입니다. @Async가 작동하려면 응용 프로그램 컨텍스트에서 개체를 검색하고 검색된 복사본의 메서드를 호출해야합니다. 내부적으로 호출하면 작동하지 않습니다.

    내부 @Transactional 메소드를 호출하려고 할 때도 똑같은 일이 발생합니다. 자세한 내용은 @Transactional을 설명하는 Spring 문서의 끝에있는 Note : 섹션을 참조하십시오.

    또한, 미래의 반환 값에 대해 .get ()을 즉시 호출하는 방식이 올바르지 않습니다. 병렬로 처리하기를 원하면 모든 작업을 제출하고 .get ()을 통해 각 작업을 검색해야합니다.

    일반적인 접근법은 프록 싱 문제를 처리하는 것이고 TestService를 주입하는 별도의 서비스 클래스를 생성하고 @Async 서비스 메소드를 직접 호출하는 것입니다.

    @Service public class TestServiceHelper {
        @Autowired
        TestService testService;
    
        public SomeDataType getSOmeDataType() {
            try {
                // Invoke all of them async:
                Future<List<DataType>> a = testService.retrieveDataA();
                Future<List<DataType>> b = testService.retrieveDataA();
                Future<List<DataType>> c = testService.retrieveDataA();
                Future<List<DataType>> d = testService.retrieveDataA();
                Future<List<DataType>> e = testService.retrieveDataA();
    
                // Wait for each sequentially:
                List<DataType> aList = a.get();
                List<DataType> bList = b.get();
                List<DataType> cList = c.get();
                List<DataType> dList = d.get();
                List<DataType> eList = e.get();
    
                // do work with lists here ...
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            catch (ExecutionException e) {
                e.printStackTrace();
            }
            return referralDetailsReferenceData;
        }
    }
    

    위의 개별 서비스 빈 (매우 해킹 된 / 권장하지 않음!)의 대안은 객체를 자체에 삽입하고 삽입 된 복사본을 사용하여 @Async 메소드를 호출하는 것입니다.

  2. from https://stackoverflow.com/questions/17735455/spring-3-x-async-methods-not-called-concurrently-by-task-executor by cc-by-sa and MIT license