Bonjour,
J'ai une ConcurrentAccessException dans un stateful session bean avec le code suivant (j'ai simplifié) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 public class MyServlet extends HttpServlet { @EJB private SLSBeanLocal slsbean; ... protected void processRequest(HttpServletRequest request, HttpServletResponse response) { response.getOutputStream().write(slsbean.test()); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 @Stateless public class SLSBean implements SLSBeanLocal { @EJB private SLSBeanLocal slsbean; private String test() { try { sfsbean.init(); String hello = sfsbean.getHello(); ... some computation that can throw exceptions String world = sfsbean.getWorld(); return hello + world; } catch (Exception e) { return sfsbean.handleError(e); } } }Le bean a un attribut de transaction REQUIRES_NEW, parce qu'une Exception qui rollback la transaction dans le stateless ne doit pas affecter les prochains appels au stateful bean (p.ex des appels pour traiter l'erreur).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 @Stateful @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public class SFSBean implements SFSBeanLocal { private Locale lang; public void init() { ... lang = ...; } public String getHello(){ ... computation/entitymanager usage, returns internationalized response (based on lang) } public String getWorld(){ ... computation/entitymanager usage, returns internationalized response (based on lang) } public String handleError(Exception e){ ... computation/entitymanager usage, returns internationalized response (based on lang) } }
A cause de cet attribut de transaction, si le stateful bean était stateless, il serait repoolé après chaque appel, celà peut faire qu'une autre instance soit utilisée. C'est pourquoi je l'ai changé en statefull (à cause du champ lang).
Mais maintenant j'ai de temps en temps des ConcurrentAccessExceptions, je ne sais pas pourquoi et je ne sais pas comment résoudre le cas.
A ce que je comprends :
Le servlet utilise un stateless bean, donc il utilisera n'importe quelle instance libre de SLSBean ou il en créera une nouvelle.
Le stateless bean injecte le statefull lors de sa création et utilisera toujours le même SFSBean et il lui est exclusif (il ne sera jamais utilisé par une autre instance de SLSBean).
Donc, comment est-ce que celà peut déclancher une ConcurrentAccessException sur le statefull bean?
Partager