2012-02-24 19 views
5

Abbiamo un'applicazione web utilizzando le seguenti tecnologie: JSF 2.0, EJB 3.1, JPA 2.0, JBoss AS 7.1 finalenon entrata cache in uso

volte otteniamo la seguente eccezione dal nulla:

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] ... 

Ho cercato nel web da un po 'di tempo ma non sono riuscito a trovare alcuna soluzione. Qualcuno sa questo tipo di errore?

risposta

3

Mi sono guardato in giro perché ho un problema simile. Ho trovato solo due possibili spiegazioni: o il tuo bean stateful è scaduto (predefinito su 5000 secondi su AS7.1), o stai passando un riferimento a SFSB da un thread a un altro - quale (è suggerito su the jboss forum non è consentito.Se il primo, aumentare il timeout o rilevare l'eccezione.Se quest'ultimo, ha jboss iniettare il bean stateful ovunque sia necessario piuttosto che passarlo in giro.

Il problema che sto avendo è che Non è neanche uno di quelli per me.Ho solo un bean stateful nel setup di test, che viene iniettato separatamente nei vari bean privi di stato - e posso generare l'eccezione entro pochi secondi dall'inizio del test. per rintracciare dove sto andando male - se hai trovato una soluzione alternativa al tuo problema potresti postare per favore?

Rgds, James

Ho ristretto l'accesso a un accesso simultaneo: posso eseguire molte richieste sequenziali, ma solo alcune "concorrenti" prima che ciò accada. (Inserisco concomitanti tra virgolette perché sto sincronizzando su un blocco tenuto dall'ejb @SessionScoped quindi l'unica chiamata simultanea possibile è al metodo getLock() che ho creato su di esso).

Sono totalmente confuso dal fatto che Weld consenta o impedisca l'accesso simultaneo ai bean EJB @SessionScoped. Ho letto che Seam serializza l'accesso (e Weld è nato da Seam) ma non so se questo è effettivamente il caso. Se lo è, allora qualcos'altro sta causando la morte del mio fagiolo. È facilmente riproducibile attraverso l'accesso simultaneo da bean separati da @Stateless.

+0

Sì, hai ragione.Siamo giunti alla stessa conclusione e abbiamo rifattorizzato alcuni dei nostri metodi in modo tale che un bean di sessione non venga chiamato più di una volta. Inoltre, disattiviamo i pulsanti dopo che l'utente lo ha premuto per evitare chiamate simultanee. – Primi

0

Ok, posso fornire quello che penso sia una risposta più accurata ora. Non ero in grado di rinunciare a consentire l'accesso simultaneo all'ejb stateful perché la mia app utilizza ajax, quindi le chiamate simultanee sono inevitabili. Non riesco a ricordare dove ho trovato il riferimento, ma capisco che l'accesso simultaneo a un bean con stato dovrebbe essere serializzato dal contenitore sotto EJB3.1 - quindi avrei dovuto stare bene.

Ho finito per cercare di tracciare la mia strada attraverso la fonte JBoss AS7, e penso di aver trovato il problema (attualmente in discussione qui on the jboss AS7 forum). Sembra un bug - jboss sincronizza solo l'accesso se la tua chiamata è all'interno di una transazione attiva (BMT o CMT). Se non lo è, allora la sincronizzazione fallisce - e non è possibile (per quanto posso immaginare) sincronizzare o bloccare te stesso, perché hai sempre accesso solo a un proxy al bean, non all'istanza sottostante. La sincronizzazione su un proxy è inutile per qualcosa di diverso dal/i thread in cui è presente il proxy.

La soluzione per il momento è garantire che tutte le chiamate che potrebbero essere simultanee vengano incluse in una transazione. Sono rimasto piacevolmente sorpreso nel constatare che il sovraccarico delle prestazioni di apertura e chiusura di una transazione così frequente su EXTENDED PersistenceContext era molto piccolo - ma non l'ho spinto molto duramente :)

Sospetto che il problema riguardi tutte le versioni AS7 , ma l'ho confermato solo su AS7.1.

+0

Nel nostro caso abbiamo molti metodi annotati con @TransactionAttribute (TransactionAttributeType.NOT_SUPPORTED). Quindi, se ho capito bene, la modifica del tipo a REQUIRES_NEW dovrebbe impedire l'eccezione? (fyi iniettiamo la maggior parte degli SFSB in bean gestiti JSF) – Primi

+0

Sì assolutamente. Vorrei andare con REQUIRES_NEW REQUIRED, quindi il metodo prenderà parte a una transazione esistente se ce n'è una, o la creerà da sola se non lo è. Ho passato giorni a capirlo - non mi piace molto rifattorizzare il mio dominio del codice per piegare gli strumenti, preferisco piuttosto piegare gli strumenti. Detto questo sono un amatore completo, quindi probabilmente potrei fare meglio con le mie battaglie! – user1180316