2012-04-26 36 views
12

Se la mia applicazione Web e l'applicazione ejb si trovano sulla stessa macchina (sulla stessa JVM) e tutte le chiamate ejb sono chiamate locali, l'uso di ThreadLocal creerà problemi durante il trasferimento di informazioni da Web a ejb?Uso threadLocal nell'applicazione aziendale

Qualsiasi soluzione alternativa se le chiamate ejb sono remote? Le informazioni ThreadLocal saranno disponibili dall'applicazione Web all'applicazione ejb? L'utilizzo di ThreadLocal è consigliabile in tale scenario?

risposta

12

Per la prima domanda, non vi è alcun problema finché si rimuovono le variabili ThreadLocal alla fine di ogni chiamata. Questo è importante perché contenitori (servlet o ejb) tipicamente threadpool utente e quindi riutilizzano thread, questo ha due effetti: una "chiamata" può vedere informazioni threadlocal provenienti da una chiamata precedente e se si rimuove un'app dal contenitore senza arrestare la JVM alcune classi potrebbero non essere raccolte automaticamente perché sono ancora referenziate da un thread del contenitore. Quindi metti i dati in un threadlocal in un blocco try/finally e rimuovi nella parte finale.

Ecco un post che mostra un modo per gestire il problema: ThreadLocal in web applications

Per la seconda domanda come dati è ThreadLocal non sarà disponibile con una chiamata remota, è necessario aggiungere un parametro per le interfacce, estrarre ThreadLocal i dati da un lato e ricrearlo dall'altra parte ...

+1

Grazie. Fondamentalmente sto aggiungendo funzionalità multilingue a un'applicazione ee esistente, senza dover modificare gran parte del codice. Imposerò la lingua informazioni nella sessione HTTP e quindi utilizzare tali informazioni nella sessione HTTP per impostare il valore in 'ThreadLocal'. Dovrà quindi identificare un posto nell'applicazione (probabilmente HTTPFilter) che viene chiamato prima di ogni richiesta e impostare il valore in 'ThreadLocal 'da HTTPSession. Ciò garantirà che sia disponibile in EJB che alla fine verrà passato come un parametro di database. –

+0

Ciò assicurerà che anche se non lo rimuovo, verrebbe sovrascritto ogni volta. Grazie per la tua risposta. –

0

Dipende da quali informazioni si stanno passando! La prima domanda è troppo generica. Suggerisco di leggere il JavaDoc relativo a ThreadLocal here.

ThreadLocal vive dal lato server dell'applicazione e viene utilizzato per consentire a Thread di proteggere le chiamate degli oggetti Thread.

+1

Il javadoc di ThreadLocal non sarà quasi sufficiente. Non sai con certezza in che modo il server gestirà i thread, li legherà alle richieste, ecc. – ymajoros

1

tutte le chiamate EJB sono chiamate locali, sarà l'uso di ThreadLocal creare alcun problema, mentre

No, hai risposto da solo alla tua domanda. Poiché le chiamate sono locali, vengono eseguite nel contesto di un thread.

Qualsiasi soluzione alternativa se le chiamate ejb sono remote?

Nel caso di chiamate remote, il container Java EE verrà eseguito in un altro JVM, si pongono i propri thread per gestire la richiesta RMI ingresso, non c'è modo per un contenitore Java EE remoti, per conoscere filo variabili locali che sono state dichiarate dall'altra parte. Passalo come oggetto parametro.

0

Per le chiamate locali, il ThreadLocal dovrebbe funzionare correttamente, purché tutto sia eseguito nello stesso thread.

Per le chiamate remote, che possono potenzialmente essere eseguite su un server diverso, è necessario trovare qualcos'altro. Passa tutti i valori come parametri (che funzioneranno, ma introduce complessità nel codice) o usi qualcosa come una cache distribuita, ad es. Hazelcast, che funzionerà come un globale HashMap, a cui tutti i nodi del cluster hanno accesso.

1

Quando si utilizza EJB 3.1 è possibile passare informazioni contestuali nello EJBContext utilizzando il suo context data. Questo è solo un Map<String,Object>.

2

ThreadLocal non deve essere utilizzato in contesti EJB.Non si può garantire che le invocazioni del metodo EJB siano tutte sullo stesso thread (ovviamente dovrebbe essere).

In EJB c'è una chiamata di approccio diverso TransactionSyncrhonizationRegistry. Vedi Explanation/Usage per ulteriori dettagli.

0

ThreadLocal non può essere utilizzato con certezza del 100% nelle applicazioni Web. Semplicemente non hai la garanzia che un thread sarà usato per una sessione. Dal mio punto di vista questo può ottenere un buco di sicurezza molto difficile da trovare!

non funziona per me, restituisce sempre null!

Ho anche provato TransactionSynchronizationRegistry, ma ottengo anche null.

L'unica cosa che ha funzionato è usare JAAS come soluzione alternativa. Ma non è una buona soluzione.

Problemi correlati