EJB @Asynchronous 在 JSF 中检索实时插入的行似乎是线程锁定的
EJB @Asynchronous to retrieve real time inserted row in JSF seems to be thread locked
我正在努力实现以下目标:
EJB3 单例
@Singleton
@Startup
public class SomeSingleton implements SomeSingletonLocal {
// Entity Manager injection
private EntityManager _entity_manager;
@Override
@Asynchronous
public void createScenario(){
method1();
method2();
// ...
}
public void method1(){
// Persist an Event in a Database.
}
public void method2(){
// Persist an Event in a Database.
}
}
托管 Bean
@ManagedBean
@RequestScoped
public class SomeManagedBean{
// Entity Manager injection
private EntityManager _entity_manager;
@EJB
private SomeSingletonRemote _singleton;
public void createScenario(){
_singleton.createScenario();
}
public List<Event> getEventList(){
// Retrieve events from database
}
}
JSF 视图
<h:form>
<p:commandButton value="Start Long Stuff"
actionListener="#{SomeManagedBean.createScenario}" />
<h:outputText id="count" value="#{SomeManagedBean.getEventList.size()}" />
<p:poll interval="1" update="count" />
</h:form>
日志
->SomeManagedBean.getEventList()
<-SomeManagedBean.getEventList() // Size = 0
// Buton clicked
->SomeManagedBean.createScenario()
->SomeSingleton.createScenario()
<-SomeManagedBean.createScenario()
->SomeManagedBean.getEventList() // will end at the end of SomeSingleton.createScenario
->SomeSingleton.method1()
<-SomeSingleton.method1() // persist
...
->SomeSingleton.methodN()
<-SomeSingleton.methodN() // persist
<-SomeSingleton.createScenario()
<-SomeManagedBean.getEventList() // size = N
我预计在两次 methodI() 调用之间(即每秒)至少调用一次 getEventList。当进入SomeSingleton.createScenario()时,不知道为什么getEventList被暂停了。
看起来实体管理器或createScenario 中的事务有锁。这是重入问题吗?
A @Singleton
确实默认 read/write 锁定。这与事务没有严格关系,而是与并发有关。另见 a.o。 Java EE 7 tutorial on the subject.
解决它的一种方法是设置@ConcurrencyManagement
to BEAN
。通过这种方式,您基本上告诉容器根本不用担心并发问题,您自己承担所有责任。
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class SomeSingleton {}
另一种方法是在 class 或只读方法上显式设置 @Lock
to READ
,以便可以同时调用它们。只有在同一实例上调用具有显式 @Lock(LockType.WRITE)
的方法时,才会发生锁定。
@Singleton
@Lock(LockType.READ)
public class SomeSingleton {}
我正在努力实现以下目标:
EJB3 单例
@Singleton
@Startup
public class SomeSingleton implements SomeSingletonLocal {
// Entity Manager injection
private EntityManager _entity_manager;
@Override
@Asynchronous
public void createScenario(){
method1();
method2();
// ...
}
public void method1(){
// Persist an Event in a Database.
}
public void method2(){
// Persist an Event in a Database.
}
}
托管 Bean
@ManagedBean
@RequestScoped
public class SomeManagedBean{
// Entity Manager injection
private EntityManager _entity_manager;
@EJB
private SomeSingletonRemote _singleton;
public void createScenario(){
_singleton.createScenario();
}
public List<Event> getEventList(){
// Retrieve events from database
}
}
JSF 视图
<h:form>
<p:commandButton value="Start Long Stuff"
actionListener="#{SomeManagedBean.createScenario}" />
<h:outputText id="count" value="#{SomeManagedBean.getEventList.size()}" />
<p:poll interval="1" update="count" />
</h:form>
日志
->SomeManagedBean.getEventList()
<-SomeManagedBean.getEventList() // Size = 0// Buton clicked
->SomeManagedBean.createScenario()
->SomeSingleton.createScenario()
<-SomeManagedBean.createScenario()->SomeManagedBean.getEventList() // will end at the end of SomeSingleton.createScenario
->SomeSingleton.method1()
<-SomeSingleton.method1() // persist
...
->SomeSingleton.methodN()
<-SomeSingleton.methodN() // persist<-SomeSingleton.createScenario()
<-SomeManagedBean.getEventList() // size = N
我预计在两次 methodI() 调用之间(即每秒)至少调用一次 getEventList。当进入SomeSingleton.createScenario()时,不知道为什么getEventList被暂停了。
看起来实体管理器或createScenario 中的事务有锁。这是重入问题吗?
A @Singleton
确实默认 read/write 锁定。这与事务没有严格关系,而是与并发有关。另见 a.o。 Java EE 7 tutorial on the subject.
解决它的一种方法是设置@ConcurrencyManagement
to BEAN
。通过这种方式,您基本上告诉容器根本不用担心并发问题,您自己承担所有责任。
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class SomeSingleton {}
另一种方法是在 class 或只读方法上显式设置 @Lock
to READ
,以便可以同时调用它们。只有在同一实例上调用具有显式 @Lock(LockType.WRITE)
的方法时,才会发生锁定。
@Singleton
@Lock(LockType.READ)
public class SomeSingleton {}