ConcurrentAccessException avec un stateful session bean
Bonjour,
J'ai une ConcurrentAccessException dans un stateful session bean avec le code suivant (j'ai simplifié) :
Code:
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:
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);
}
}
} |
Code:
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)
}
} |
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).
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?