Frage

Ich versuche, Integrationstests für eine Legacy-Anwendung auf Weblogic eingesetzt erstellen 8.1 eine Unterklasse von AbstractTransactionalJUnit4SpringContextTests verwendet wird.

Meine Testmethode hat folgende Anmerkungen:

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

Meine Testklasse auch Referenzen Bohnen vom Typ org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean, die Proxy der auf meinem WebLogic Server bereitgestellt EJBs.

Wenn ich Methoden auf diesem Proxy-Bean in einer sequentiellen Weise rufe in meinem Testverfahren sichern die Transaktion Rollen richtig am Ende des Tests.

z. :

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

Allerdings würde Ich mag 2 parallele Anrufe zur gleichen EJB-Methode machen. Deshalb habe ich eine innere Klasse gemacht, dass Geräte aufrufbare, um meine Methoden in 2 verschiedenen Themen und Hoffnung zu nennen diejenigen parallel laufen zu lassen.
Aber dies zu tun scheint die ejb Methoden zu machen, außerhalb meiner Transaktion aufgerufen werden, und es wird nichts zurückgerollt.

Hier ist, was die vollständige Testklasse möchte, wenn ich die Methodenaufrufe parallel laufen:

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;   
    } 
}

Gibt es eine Möglichkeit, diese Rollbacks ???

zu machen

Danke für Ihre Hilfe.

Grüße,

Philippe

War es hilfreich?

Lösung

Nicht automatisch, nein. Das Problem ist, dass die beiden zusätzlichen Fäden nehmen nicht an der Transaktion, damit ihre Handlungen nicht Rollbacks.

Was ist der Zweck der beiden parallelen Ausführungen? Sie werden kaum Test mit diesem Ansatz für Parallelitätsprobleme können, wenn es das ist, was Sie anstreben.

Edit: Das Problem ist, dass für Concurrency Probleme zu testen ist sehr hart, weil die Tests sind, im besten Fall, probabilistische - Erfolg oder Misserfolg hängt von subtilen Timing-Problemen, die nur auf dem Milliardstel Lauffläche können . Siehe dieser Serverside Artikel für eine gute Zusammenfassung der Grundlagen.

Als Faustregel sollte zu vermeiden Hand-Codierung Einfädeln möglich sein, wenn, wie es schwer ist richtig und schwierig zu testen zu bekommen. Wenn Sie können, vermeidet gemeinsamer Zustand zwischen Threads, und wenn es kein Weg drum herum ist, stützen sich auf den gleichzeitigen Datenstrukturen und asynchronen Zieher aus dem java.util.concurrent Paket.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top