问题描述
我想实现如下:
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()结果
&LT; -SomeManagedBean.getEventList()//大小= 0
//布顿点击搜索
- > SomeManagedBean.createScenario()结果
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; - > SomeSingleton.createScenario()结果
&LT; -SomeManagedBean.createScenario()
// Buton clicked
->SomeManagedBean.createScenario()
->SomeSingleton.createScenario()
<-SomeManagedBean.createScenario()
- > SomeManagedBean.getEventList()//将结束在SomeSingleton.createScenario结果的末尾
- > SomeSingleton.method1()结果
&LT; -SomeSingleton.method1()//坚持结果
...结果
- > SomeSingleton.methodN()结果
&LT; -SomeSingleton.methodN()//坚持
->SomeManagedBean.getEventList() // will end at the end of SomeSingleton.createScenario
->SomeSingleton.method1()
<-SomeSingleton.method1() // persist
...
->SomeSingleton.methodN()
<-SomeSingleton.methodN() // persist
&LT; -SomeSingleton.createScenario()
<-SomeSingleton.createScenario()
&LT; -SomeManagedBean.getEventList()//大小= N
<-SomeManagedBean.getEventList() // size = N
我预计至少有一个呼叫两个methodI()调用之间getEventList(即每秒)。当它在SomeSingleton.createScenario(进入),我不知道为什么getEventList暂停。
I expected at least one call to getEventList between two methodI() call (ie. each second). When it enters in SomeSingleton.createScenario(), I dont know why getEventList is paused.
它看起来像有与实体管理器或内部createScenario事务的锁。那是一个重入的问题?
It looks like there is a lock with the entity manager or the transaction inside createScenario. Is that a reentrance problem ?
推荐答案
A @Singleton
确实是默认的读/写锁定。这不是严格相关的交易,但并发性。另请参见A.O。 。
A @Singleton
is indeed by default read/write locked. This is not strictly related to transactions, but to concurrency. See also a.o. Java EE 7 tutorial on the subject.
要解决它的方法之一是设置<$c$c>@ConcurrencyManagement$c$c>到<$c$c>BEAN$c$c>.这样,你基本上告诉容器都不用担心并发和你承担自己的全部责任。
One way to solve it is to set the @ConcurrencyManagement
to BEAN
. This way you basically tell the container to not worry about concurrency at all and that you take all responsibility on your own.
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class SomeSingleton {}
另一种方法是明确设置以。只有当一个方法的显式 @Lock(LockType.WRITE)
上调用同一个实例,那么就会出现锁。
Another way is to explicitly set @Lock
to READ
on the class or the read-only methods so that they can concurrently be invoked. Only when a method with an explicit @Lock(LockType.WRITE)
is invoked on the same instance, then the lock will occur.
@Singleton
@Lock(LockType.READ)
public class SomeSingleton {}
这篇关于EJB @Asynchronous检索实时插入行中JSF似乎是线程锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!