How singleton is javax.ejb.Singleton in a clustered environment?
Asked Answered
D

3

10

I need to maintain a simple counter that is unique within the application, for all users and all nodes in a clustered environment. I thought about using the singleton session bean annotation javax.ejb.Singleton like so:

package foo;

import javax.ejb.Singleton;

@Singleton
public class Bean {
    private int counter;
    [...]
}

This looks simple, but I could not find an answer if this works as desired in a clustered environment. Would every node of the cluster have it's own instance or not?

Of course I could persist the bean in a database, but it's really only a counter and doing so would be overkill. Also, I want the counter to reset on application crash or restart, so persisting it would create more problems than it solves.

Deth answered 7/4, 2015 at 16:25 Comment(3)
Even if you choose to persist it, the solution might not be a full proof one. What if a request on node 2 comes up while node 1 is busy persisting the updated counter value ? :-)Retriever
If you are using db which supports sequences, you can use them. Why? Because I think its the best reliable solution. In your singleton you can use lifecycle annotations to perform sequence reset operation, whether on startup or destroy, depends on you.Septi
I need to count up and down and the app server has a different life cycle than the database, so that doesn't work, but thanks.Deth
D
14

Would every node of the cluster have it's own instance or not?

Yes, each cluster node will have a different Singleton instance. Therefore, @Singleton annotation is not the solution for your problem.

Take in mind that Java EE specification doesn't define any kind of cluster behavior. You need to search for specific vendor solution to achieve this kind of requirement. Just as an example see this link.

Deranged answered 7/4, 2015 at 19:45 Comment(2)
Thanks. I wonder if there is an option without depending on a particular product. Maybe hack JNDI or so?Deth
I think it could be possible to implement your own solution, but you will face problems (challenges) that already were resolved for specialized developer teams.Deranged
C
3

You could use hazelcast . It's a distributed in-memory key-value store. Seems like it would be a perfect fit. It also implements JSR-107 which is the JCache spec.

Calcar answered 10/4, 2015 at 2:0 Comment(5)
Do you have any example or tutorial?Assistance
You could use a distributed map and retrieve the singleton by key (docs.hazelcast.com/imdg/latest/data-structures/map.html) or you could use the IAtomicReference and retrieve the singleton by name (docs.hazelcast.com/imdg/latest/data-structures/…)Calcar
Thank you! What's the Hazelcast default map name was used to storage the Clustered Singleton EJB or I have to define it and implement the map creation and add the clustered singleton EJB by myself?Assistance
You would just create a map named whatever you like and then get that map from hazelcast. You wouldn't need a Singleton EJB. Just get your value from the hazelcast map whenever you need it. It will be the same across all instances.Calcar
If you're just trying to keep a single counter across all servers use an IAtomicLong. That would be the easiest.Calcar
E
-2

Ha singleton is an approach. As an advance, there are some limitations. If you read, you will have a @stateless bean that access to the service through a "getValue()" method. The get value calls a singleton bean's methods and gives to you a value... all right until there.

But if you need to operate with the bean, a strategy should return a SingletonBean instance through get value, but.. you will have more instances of that singleton bean .... and there is the problem.

Expansion answered 16/9, 2015 at 15:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.