Frage

Ich bin mit TestNG Ausdauer Frühling Module zu testen (JPA + Hibernate) AbstractTransactionalTestNGSpringContextTests als Basisklasse verwendet wird. Alle wichtigen Teile @Autowired, @TransactionConfiguration, @Transactional gut funktionieren.

Das Problem kommt, wenn ich versuche, Test in parallelen Threads mit threadPoolSize = x, invocationCount = y TestNG Anmerkung auszuführen.

WARNING: Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@174202a] 
to process 'before' execution of test method [testCreate()] for test instance [DaoTest] java.lang.IllegalStateException:
Cannot start new transaction without ending existing transaction: Invoke endTransaction() before startNewTransaction().
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:123)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextBeforeTestMethod(AbstractTestNGSpringContextTests.java:146)

... Hat jemand dieses Problem konfrontiert?

Hier ist der Code:

@TransactionConfiguration(defaultRollback = false)
@ContextConfiguration(locations = { "/META-INF/app.xml" })
public class DaoTest extends AbstractTransactionalTestNGSpringContextTests {

@Autowired
private DaoMgr dm;

@Test(threadPoolSize=5, invocationCount=10)
public void testCreate() {
    ...
    dao.persist(o);
    ...
}
...

Update: Es scheint, dass AbstractTransactionalTestNGSpringContextTests Transaktion für Hauptthread nur hält, wenn alle anderen Test Threads keine eigene Transaktionsinstanz erhalten. Der einzige Weg, das zu lösen ist AbstractTestNGSpringContextTests zu verlängern und pflegen Transaktion programmatisch (statt @Transactional Annotation) pro jede Methode (d.h. mit TransactionTemplate):

@Test(threadPoolSize=5, invocationCount=10)
public void testMethod() {
    new TransactionTemplate(txManager).execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            // transactional test logic goes here
        }
    }
}
War es hilfreich?

Lösung

Die Transaktion muss im selben Thread gestartet wird, sind hier weitere Details:

Spring3 / Hibernate3 / TestNG: einige Tests geben LazyInitializationException, einige nicht

Andere Tipps

Glauben Sie nicht, diese eher kommt von org.springframework.test.context.TestContextManager nicht sicher sein Thread (siehe https://jira.springsource.org/browse/SPR-5863 )?

stand ich das gleiche Problem, wenn ich wollte meine Transactional TestNG Tests parallel starten und Sie können sehen, dass der Frühling tatsächlich die Transaktion an der richtigen Thema zu binden versucht.

Jedoch dies nicht gelingt zufällig mit dieser Art von Fehlern. Ich verlängerte AbstractTransactionalTestNGSpringContextTests mit:

@Override
@BeforeMethod(alwaysRun = true)
protected synchronized void springTestContextBeforeTestMethod(
        Method testMethod) throws Exception {
    super.springTestContextBeforeTestMethod(testMethod);
}

@Override
@AfterMethod(alwaysRun = true)
protected synchronized void springTestContextAfterTestMethod(
        Method testMethod) throws Exception {
    super.springTestContextAfterTestMethod(testMethod);
}

(der Schlüssel der synchronisierten ...)

und es funktioniert jetzt wie ein Zauber. Ich kann nicht für den Frühling 3.2 warten aber so, dass es komplett parallized werden kann!

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