Reputation:
I would appreciate your advice about an issue I have.
I'm working with jboss, EJB 3.1 environment.
each time the user entering a specific screen, it should be a trigger for creating a tree data type which based on a data that saved on the database. this tree calculation can take some time, and it's can be heavy on performance.
the following requests are sent from 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.
when building this I should take into consideration that multiple users can try to perform each one of those actions simultaneously.
I've thought about implementing it as a cache as follow :
@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;
}
}
the issue I have with that is that there can be a scenario in which :
I'm trying to think a bout using a read lock in some way (instead of the isTreeReady flag), but I can't think about any that will fit my needs.
do you have an idea what can I do?
thanks.
Upvotes: 1
Views: 1241
Reputation: 11622
By using @Singleton
annotation, the concurrency is managed by the container. If one user invokes a method, then all methods have write lock & requests from other users for any method must have to wait for the previous one to return.
But you have applied lock explicitly on refresh() method, so other methods - isTreeReady()
, getTree()
etc. can be accessed concurrently by other users. Therefore if you remove lock on refresh()
method, then only one user will be able to access a method at a time.
LockType.READ : Annotate a singleton’s business or timeout method with @Lock(LockType.READ) if the method can be concurrently accessed, or shared, with many clients.
LockType.WRITE : Annotate the business or timeout method with @Lock(LockType.WRITE) if the singleton session bean should be locked to other clients while a client is calling that method.
Else, you can gain better control by using bean manager concurrency by using annotation @ConcurrencyManagement(ConcurrencyManagementType.BEAN)
on singleton bean. But you have to manage method synchronization, concurrency explicitly on your own.
I am not able to figure out exact the scenario from question, but using proper locking strategy might resolve the issue.
Upvotes: 1