在EJB Singleton上调用异步和同步方法

时间:2015-11-11 10:30:44

标签: jsf java-ee asynchronous singleton ejb-3.1

我正在努力实现以下目标:

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”按钮时,我们必须等到方法完成才能按下另一个按钮。
你能告诉我我错了吗?

1 个答案:

答案 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)可能更有意义。