感谢您就我遇到的问题提出建议。
我正在使用jboss,EJB 3.1环境。
每次用户进入特定屏幕时,它应该是基于保存在数据库上的数据创建树数据类型的触发器。 这个树计算可能需要一些时间,而且性能可能很高。
从UI发送以下请求:
1. refreshTree - a trigger for building the tree
2. isTreeReady - indicating whether the tree is ready to use, and called every x amount of time
3. getTree - return the tree.
在构建时,我应该考虑到多个用户可以尝试同时执行这些操作中的每一个。
我已经考虑将其实现为缓存,如下所示:
@singleton
public class TreeCache{
@EJB
MyTree tree;
boolean isTreeReady = false;
@Lock(LockType.WRITE)
public void refresh(){
isTreeReady = false;
tree = calulcateTree() \\ heavy calculation
isTreeReady = true;
}
public boolean isTreeReady(){
return isTreeReady;
}
public MyTree getTree(){
return tree;
}
}
我遇到的问题是可能存在以下情况:
我正在尝试以某种方式使用读锁定(而不是isTreeReady标志),但我无法考虑任何符合我需求的内容。
你知道我该怎么办?
感谢。
答案 0 :(得分:1)
通过使用@Singleton
注释,并发性由容器管理。如果一个用户调用一个方法,那么所有方法都有写锁定&其他用户对任何方法的请求必须等待前一个方法返回。
但是您已经在refresh()方法上明确应用了锁,因此其他用户可以同时访问其他方法 - isTreeReady()
,getTree()
等。因此,如果您删除refresh()
方法上的锁定,则一次只能有一个用户访问某个方法。
LockType.READ:如果可以与许多客户端同时访问或共享该方法,则使用@Lock(LockType.READ)注释单例的业务或超时方法。
LockType.WRITE:使用@Lock(LockType.WRITE)注释业务或超时方法,如果 当客户端调用该方法时,单例会话bean应该被锁定到其他客户端。
否则,通过在singleton bean上使用注释@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
,可以通过使用bean管理器并发获得更好的控制。但是你必须自己明确地管理方法同步和并发。
我无法确定问题的具体情况,但使用正确的锁定策略可能会解决问题。