문제

AbstractTransactionalJunit4SpringContextTests의 서브 클래스를 사용하여 WebLogic 8.1에 배포 된 레거시 응용 프로그램에 대한 통합 테스트를 만들려고합니다.

내 테스트 방법에는 다음과 같은 주석이 있습니다.

@Test
@Rollback(true)
public void testDeployedEJBCall throws Exception {...}

내 테스트 클래스는 또한 org.springframework.ejb.access.simpleremotestatementsessessessessessessessessessessessessesssectyfactorybean의 bean을 참조합니다.

테스트 방법 에서이 프록시 콩의 메소드를 시퀀싱 방식으로 호출하면 트랜잭션이 테스트가 끝날 때 올바르게 롤백됩니다.

예 :

@Test
@Rollback(true)
public void testDeployedEJBCall throws Exception {
    Long result1 = myejb.method(100L);
    Long result2 = myejb.method(200L);
    ...
}

그러나 동일한 EJB 메소드에 2 개의 병렬 호출을하고 싶습니다. 그러므로 나는 2 개의 다른 스레드로 내 방법을 호출하고 병렬로 실행하기를 희망하기 위해 호출 가능을 구현하는 내부 클래스를 만들었습니다.
그러나이를 수행하면 EJB 방법이 내 거래 밖에서 호출되는 것으로 보이며 아무것도 롤백되지 않습니다.

메소드 호출을 병렬로 실행할 때 전체 테스트 클래스가 원하는 것입니다.

import org.springframework.test.annotation.*;

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ContextConfiguration(locations = {"classpath:path/to/tests-config.xml"})
@TransactionConfiguration(defaultRollback=true)
public final class IntegrationTests extends AbstractTransactionalJUnit4SpringContextTests {
    @Autowired
    protected JndiTemplate jndiTemplate;
    @Resource
    protected Proxy myEJB;

    public IntegrationTests() {
        super();
        this.logger = Logger.getLogger(IntegrationTests.class);
    }

    @Test
    @Rollback(true)
    public void testDeployedEJBCall() throws Exception {
        // Create a thread pool for parallel execution. 
        ExecutorService exec = Executors.newFixedThreadPool(2);

        // Prepare the tasks for parallel execution
        List<CallEJBTask> tasks = new ArrayList<CallEJBTask>();
        tasks.add(new CallEJBTask(100L, this.myEJB));
        tasks.add(new CallEJBTask(200L, this.myEJB));

        // Execute all pending tasks in the exec Threadpool
        List<Future<Long>> results = exec.invokeAll(tasks);

        // Get the results of each task
        Long result1 = results.get(0).get();
        Long result2 = results.get(1).get();

        ...
    }
}

private class CallEBJTask implements Callable<Long> {
    private final Long valueToTest;
    private final MyEJB myEJB;

    public CallEJBTask(Long valueToTest, Proxy myEJBProxy)
        this.valueToTest = valueToTest;
        this.myEJB = (MyEJB)myEJBProxy;
    }

    public Long call() throws Exception {
        return getResult();
    }

    public Long getResult() {
        Long result = null;

        try {
            result = this.myEJB.method(this.patient);

        } catch (Exception e) {
            ...
        }
        return result;   
    } 
}

이 롤백을 만드는 방법이 있습니까 ???

당신의 도움을 주셔서 감사합니다.

문안 인사,

필립

도움이 되었습니까?

해결책

자동으로는 아닙니다. 문제는 두 개의 추가 스레드가 거래에 참여하지 않으므로 그들의 행동은 롤백하지 않는다는 것입니다.

두 개의 병렬 실행의 목적은 무엇입니까? 이 접근법의 동시성 문제를 테스트 할 수는 없을 것입니다.

편집하다: 문제는 동시성 문제에 대한 테스트가 매우 어렵다는 것입니다. 테스트는 기껏해야 확률 론적이기 때문에 성공 또는 실패는 10 억의 실행에만 표면적 일 수있는 미묘한 타이밍 문제에 달려 있습니다. 보다 이 서버 사이드 기사 기본 사항에 대한 좋은 요약.

경험의 규칙은 올바르게 잡기가 어렵고 테스트하기가 어렵 기 때문에 가능할 때마다 손 코드 스레딩을 피하는 것입니다. 가능하다면 스레드 사이의 공유 상태를 피하고 그 주위에 방법이 없다면 동시 데이터 구조와 비동기적 인 집행자에게 의존하십시오. java.util.concurrent 패키지.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top