我正在努力实现以下目标:
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(){
// ...
}
}
托管Bean
@ManagedBean
@RequestScoped
public class SomeManagedBean{
@EJB
private SomeSingletonRemote _singleton;
public void someLongStuff(){
_singleton.someLongStuff();
}
public void someShortStuff(){
_singleton.someShortStuff();
}
}
使用PrimeFace的JSF
<h:form>
<p:commandButton value="Start Long Stuff"
actionListener="#{SomeManagedBean.someLongStuff}" />
<p:commandButton value="Start Short Stuff"
actionListener="#{SomeManagedBean.someShortStuff}" />
</h:form>
上述代码不能异步工作。当按下“Start Long Stuff”按钮时,我们必须等到方法完成才能按下另一个按钮。
你能告诉我我错了吗?
答案 0 :(得分:2)
单例会话bean默认使用带有写锁的容器管理并发,这意味着所有方法都是独占的。如果要同时在EJB上调用多个方法,则需要使用bean托管并发:
@Singleton
@Startup
@ConcurrencyManagement(BEAN)
public class SomeSingleton implements SomeSingletonRemote {
...或者您需要指定读锁:
@override
@Asynchronous
@Lock(READ)
public void someLongStuff(){ ... }
...
@Lock(READ)
public void someShortStuff(){
// ...
}
如果你的bean方法正在进行写操作,那么在概念上使用bean管理的并发而不是@Lock(READ)
可能更有意义。