Reputation: 817
I am trying to achieve the following :
EJB3 Singleton
@Singleton
@Startup
public class SomeSingleton implements SomeSingletonRemote {
@override
@Asynchronous
public void someLongStuff(){
method1();
Thread.sleep(3000);
method2();
Thread.sleep(3000);
// ...
}
public void method1(){
// Insert an Event in a Database.
}
public void method2(){
// Insert an Event in a Database.
}
public void someShortStuff(){
// ...
}
}
Managed Bean
@ManagedBean
@RequestScoped
public class SomeManagedBean{
@EJB
private SomeSingletonRemote _singleton;
public void someLongStuff(){
_singleton.someLongStuff();
}
public void someShortStuff(){
_singleton.someShortStuff();
}
}
JSF using PrimeFace
<h:form>
<p:commandButton value="Start Long Stuff"
actionListener="#{SomeManagedBean.someLongStuff}" />
<p:commandButton value="Start Short Stuff"
actionListener="#{SomeManagedBean.someShortStuff}" />
</h:form>
The above code doesn't work asynchronously. When the "Start Long Stuff" button is pressed, we have to wait until the method is finished to be able to press the other button.
Can you tell me were I am wrong ?
Upvotes: 0
Views: 2635
Reputation: 33936
Singleton session beans by default use container-managed concurrency with write locks, which means all methods are exclusive. If you want to allow multiple methods to be called on the EJB simultaneously, you either need to use bean managed concurrency:
@Singleton
@Startup
@ConcurrencyManagement(BEAN)
public class SomeSingleton implements SomeSingletonRemote {
...or you need to specify read locks:
@override
@Asynchronous
@Lock(READ)
public void someLongStuff(){ ... }
...
@Lock(READ)
public void someShortStuff(){
// ...
}
If your bean methods are doing write operations, it probably makes more sense conceptually to use bean-managed concurrency rather than @Lock(READ)
.
Upvotes: 2