2012-02-24 11 views
5

Tenemos una aplicación web utilizando las siguientes tecnologías: JSF 2.0, EJB 3.1, JPA 2.0, JBoss AS 7.1 finalno entrada de caché en uso

A veces tenemos la siguiente excepción de la nada:

09:46:29,664 ERROR [org.jboss.ejb3.invocation] (http-10.99.0.10-10.99.0.10-8080-14) JBAS014134: EJB Invocation failed on component VehicleServiceBean for method public abstract java.util.List com.hji.common.service.VehicleService.findVehiclesBySearchCriteriaAndImporterIds(com.hji.common.domain.repository.VehicleRepository$VehicleSearchCriteria,java.lang.String,java.util.List,boolean): java.lang.IllegalStateException: JBAS014531: Cache entry {[36, -111, 
-104, -128, 61, -17, 73, 29, -101, 52, -7, -106, 46, -3, 44, -22]} is not in use 
      at org.jboss.as.ejb3.cache.impl.backing.NonPassivatingBackingCacheImpl.release(NonPassivatingBackingCacheImpl.java:134) [jboss-as-ejb3-7.1.0.Final.jar:7.1.0.Final] 
      at org.jboss.as.ejb3.cache.impl.backing.NonPassivatingBackingCacheImpl.release(NonPassivatingBackingCacheImpl.java:56) [jboss-as-ejb3-7.1.0.Final.jar:7.1.0.Final] 
      at org.jboss.as.ejb3.cache.spi.impl.AbstractCache.release(AbstractCache.java:76) [jboss-as-ejb3-7.1.0.Final.jar:7.1.0.Final] 
      at org.jboss.as.ejb3.cache.spi.impl.AbstractCache.release(AbstractCache.java:39) [jboss-as-ejb3-7.1.0.Final.jar:7.1.0.Final] 
      at org.jboss.as.ejb3.component.stateful.StatefulSessionSynchronizationInterceptor.releaseInstance(StatefulSessionSynchronizationInterceptor.java:197) ... 
**Caused by: java.lang.IllegalStateException: JBAS014531: Cache entry {[36, -111, -104, -128, 61, -17, 73, 29, -101, 52, -7, -106, 46, -3, 44, -22]} is not in use** 
      at org.jboss.as.ejb3.cache.impl.backing.NonPassivatingBackingCacheImpl.release(NonPassivatingBackingCacheImpl.java:134) [jboss-as-ejb3-7.1.0.Final.jar:7.1.0.Final] 
      at org.jboss.as.ejb3.cache.impl.backing.NonPassivatingBackingCacheImpl.release(NonPassivatingBackingCacheImpl.java:56) [jboss-as-ejb3-7.1.0.Final.jar:7.1.0.Final] 
      at org.jboss.as.ejb3.cache.spi.impl.AbstractCache.release(AbstractCache.java:76) [jboss-as-ejb3-7.1.0.Final.jar:7.1.0.Final] 
      at org.jboss.as.ejb3.cache.spi.impl.AbstractCache.release(AbstractCache.java:39) [jboss-as-ejb3-7.1.0.Final.jar:7.1.0.Final] ... 

He estado buscando en la web desde hace un tiempo pero no he podido encontrar ninguna solución. ¿Alguien sabe este tipo de error?

Respuesta

3

He estado buscando porque tengo un problema similar. Solo he encontrado dos explicaciones posibles: o su bean con estado ha agotado el tiempo de espera (el valor predeterminado es 5000 segundos en AS7.1), o está pasando una referencia al SFSB de un hilo a otro, que (se sugiere en the jboss forum no está permitido. Si el primero, ya sea aumentar el tiempo de espera o atrapar la excepción. Si este último, tiene jboss inyectar el bean con estado donde sea necesario en lugar de pasarlo.

El problema que tengo es que no es ninguno de esos para mí. Solo tengo un bean con estado en la configuración de prueba, que se inyecta por separado en los diversos beans sin estado, y puedo generar la excepción en unos pocos segundos después de comenzar la prueba. Todavía estoy intentando para localizar dónde estoy yendo mal, si ha encontrado una solución alternativa a su problema, ¿podría publicarla, por favor?

Rgds, James

Lo he reducido a acceso simultáneo. Puedo hacer muchas solicitudes secuenciales, pero solo unas pocas "concurrentes" antes de que esto ocurra. (Pongo comillas simultáneas porque estoy sincronizando en un bloqueo mantenido por el ejb @SessionScoped por lo que la única llamada concurrente posible es el método getLock() que he creado en él).

Estoy totalmente confundido sobre si Weld permite o impide el acceso concurrente a @SessionScoped @Stateful EJBs. Leí que Seam serializa el acceso (y Weld nace de Seam), pero no sé si ese es realmente el caso. Si es así, entonces algo más está causando que mi grano muera. Sin embargo, es fácilmente reproducible mediante el acceso simultáneo de beans @Stateless separados.

+0

Sí, tienes razón.Llegamos a la misma conclusión y refactorizamos algunos de nuestros métodos para que un bean de sesión no se llame más de una vez. Además, ahora desactivamos los botones después de que el usuario lo presione para evitar llamadas concurrentes. – Primi

0

Ok Puedo proporcionar lo que creo que es una respuesta más precisa ahora. No pude dejar de permitir el acceso concurrente al ejb stateful porque mi aplicación usa ajax, por lo que las llamadas concurrentes son inevitables. No puedo recordar dónde encontré la referencia, pero entiendo que el acceso concurrente a un bean con estado debe ser serializado por el contenedor bajo EJB3.1, así que debería haber estado bien.

Terminé tratando de seguir mi camino a través de la fuente JBoss AS7, y creo que encontré el problema (actualmente en discusión aquí on the jboss AS7 forum). Parece ser un error: jboss solo sincroniza el acceso si su llamada está dentro de una transacción activa (BMT o CMT). Si no es así, la sincronización falla, y no es posible (hasta donde me sea posible) sincronizar o encerrarme, porque solo tienes acceso a un proxy para el bean, no a la instancia subyacente en sí misma. La sincronización en un proxy es inútil para cualquier otra cosa que no sea la (s) hebra (s) en que existe el proxy.

La solución alternativa por ahora es asegurar que todas las llamadas que puedan ser concurrentes estén envueltas en una transacción. Me sorprendió gratamente descubrir que la sobrecarga de rendimiento de abrir y cerrar una transacción con tanta frecuencia en un PersistenceContext EXTENDIDO era muy pequeña, pero realmente no lo he impulsado demasiado.

Sospecho que el problema afecta a todas las versiones de AS7 , pero solo lo han confirmado en AS7.1.

+0

En nuestro caso, tenemos muchos métodos anotados con @TransactionAttribute (TransactionAttributeType.NOT_SUPPORTED). Entonces, si entiendo correctamente, ¿cambiar el tipo a REQUIRES_NEW debería evitar la excepción? (fyi inyectamos la mayoría de los SFSB en beans administrados JSF) – Primi

+0

Sí absolutamente. Me gustaría ir con REQUERED en lugar de REQUIRES_NEW, luego el método tomará parte en una transacción existente, si existe, o creará la suya propia si no es así. Pasé varios días pensando en esto: no me gusta mucho refaccionar mi dominio de código para doblar las herramientas, prefiero doblar las herramientas. ¡Eso dice que soy un completo aficionado, así que probablemente podría hacer para elegir mis batallas mejor! – user1180316

Cuestiones relacionadas