Pregunta

Estoy utilizando TestNG para poner a prueba los módulos de persistencia de primavera (APP) + Hibernate utilizando AbstractTransactionalTestNGSpringContextTests como clase base. Todas las partes importantes @Autowired, @TransactionConfiguration, el trabajo @Transactional muy bien.

El problema viene cuando estoy tratando de ejecutar la prueba de hilos paralelos con threadPoolSize = x, invocationCount = y anotación TestNG.

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)

... Se ha enfrentado a nadie este problema?

Este es el código:

@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);
    ...
}
...

Actualización: Parece que AbstractTransactionalTestNGSpringContextTests mantiene transacción sólo para el hilo principal cuando todos los otros hilos de prueba no consiguen su propia instancia de transacción. La única manera de resolver que es extender AbstractTestNGSpringContextTests y mantener transacción mediante programación (en lugar de anotación @Transactional) por cada método (es decir, con 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
        }
    }
}
¿Fue útil?

Solución

La transacción necesita ser iniciado en el mismo hilo, aquí hay más detalles:

Spring3 / Hibernate3 / TestNG: algunas pruebas dan LazyInitializationException, algunos no

Otros consejos

¿No cree que esta vez viene de org.springframework.test.context.TestContextManager no ser seguro para subprocesos (ver https://jira.springsource.org/browse/SPR-5863 )?

Me enfrenté al mismo problema cuando quería lanzar mis pruebas TestNG transaccionales en paralelo y se puede ver que la primavera trata en realidad para obligar a la transacción a la rosca a la derecha.

Sin embargo esto no funciona al azar con este tipo de errores. Extendí AbstractTransactionalTestNGSpringContextTests con:

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

(la tecla que se sincroniza la ...)

y ahora está trabajando como un encanto. No puedo esperar para la primavera 3,2, aunque por lo que se puede parallized completamente!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top