春のテスト:テストメソッドの実行後に、トランザクションがロールバックしません

StackOverflow https://stackoverflow.com/questions/2063511

質問

私はAbstractTransactionalJUnit4SpringContextTestsのサブクラスを使用してWebLogic 8.1上に配備レガシーアプリケーションのための統合テストを作成しようとしています。

私の試験方法は、次の注釈があります:

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

私のテストクラスでは、EJBが私のWebLogic Server上に配備プロキシタイプorg.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBeanの豆を参照します。

私は私のテスト方法で連番の方法で、このプロキシ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;   
    } 
}

???このロールバックを作るための方法があります。

ご協力いただきありがとうございます。

よろしく、

フィリップ

役に立ちましたか?

解決

未自動的に、ありません。問題は、2つの余分なスレッドは、トランザクションに参加していないので、その行動はロールバックしていないということです。

2つの並列実行の目的は何ですか?それはあなたが目指しているものである場合は、そう、このアプローチに並行性の問題をテストすることができるようになります。

の編集:の問題は、あなたのテストは、最高の状態で、確率的であるため、並行性の問題のためのテストは、非常に困難であるということです - 成功または失敗は、10億実行時にも表面だけ微妙なタイミングの問題に依存します。基本の良い要約のためのこのサーバーサイドの記事を参照してください。

親指のルールは、テストを受ける権利や困難を取得することは困難であるとして、可能な限り手コーディングスレッドを避けるためにする必要があります。あなたができる場合は、スレッド間で共有状態を回避し、そしてその周りに方法がない場合は、java.util.concurrentパッケージからの同時データ構造および非同期執行に依存しています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top