EJB design: (empty BMP entity) versus (stateless session)

  1. Ejb instances never handle two threads concurrently: concurrent calls about the same ejb run in different instances.

    I'm looking for a way to circumvent that, because i have a thread-safe implementation of a stateless server interface, and that object is heavy to construct, so i want to do it only once, and use it to process all clients.

    My idea is "publish" my implementation as a singleton in my virtual machine somehow (for example a static reference in a helper class), and make an ejb implementing the same interface, and forwarding the calls to the singleton.

    I do want an ejb in front to have remote access, distributed transactions and security. The question is, which kind of ejb?

    What would be the difference between using a stateless session bean, and using an entity bean (always te same PK) with empty BMP methods, concerning creating instances, and concurrency? Does it depend on transaction isolation level (i would guess yes)? Can i specify that for an ejb?

  2. Transaction isolation level set-up is a feature of transaction manager, i.e. database. In BMP case, you manage transaction isolation level manually through (for instance, using correspondent JDBC methods). I do not think that the idea using entity beans for the purposes other than persistance will ring the bell from architectural point of view (even without taking into consideration perfomance issues). Your idea will work, but theree is a better way to reference singleton objects in EJB world - just bind it to JNDI context.

  3. ok alex, but how can i define transaction settings (like "required" on this method, and "supported" on the other) on my singleton, if it's not an ejb? I need distributed transactions, and i prefer container managed ones (i mean declare transaction attributes per method in stead of using a transaction api).

  4. i suddenly think of a third option:

    the (home interface)

    Isn't that a singleton?
  5. Yes, home interface object is bound to JNDI and every time you get the same copy of the object. The same way you could bind a custom object.

  6. The home instance, how does it behave when many threads access it concurrently? Is that specified somewhere?

    Is this (using the home interface and home methods) the ultimate trick to make a remote accessible singleton that can handle concurrent threads?
  7. I do not think that's home interface is a solution for singleton problem. Why don't you just bind an object to JNDI as I was recommending you before?


  8. Hi Alex,
    I don't think binding objects to JNDI a good idea. In fact we did that before. If you have only one application server, it works fine. However, in a server cluster, binding an object to the cluster-wide JNDI tree, in fact that object only exists in one server (at least in WebLogic Server 6.1, binding objects to JNDI tree doesn't mean replicating that object to all servers in the cluster) So even you may look up that object via JNDI, it does return a nasty NULL value sometimes.

  9. Dright,

    So you have one instance over the cluster. I thought that's what is needded for the singleton i.e., a single instance over a cluster.

  10. Hi Pranab,
    Yes, you may say so :) However, no singleton is a good singleton if it throws a null pointer exception from time to time. And in fact, that singleton does not exist in one cluster, but in one server. When the server goes down, the singleton object is gone as well.

    Hmmm... It just came to my mind that maybe if we want a singleton over the cluster, use the entity bean approach is better. The entity bean with one specific PK really is a singleton, right?
  11. Dright Ho,

    that's a good point: an entity with a specific PK is a singleton. The bad thing about it is: you can not have many clients access it concurrently without the overhead of the container creating a different instance for each client, even when you know your implementation is thread safe.

  12. Hi Dieter,

    Let us go back one step. Why did you make all the efforts making your program tread-safe if you intended to implement your singleton with EJB?

    Maybe you did not know you would use EJB :)

    If the *singleton* EJB is deployed in just one server, there are several possible solutions as those proposed in previous articles. However when it comes to clustering, how do you define the term "thread-safe"? Don't you think is't quite confusing?

    Then let's define more precisely the term "singleton". Surely we all know what a singleton is, but what about a "cluster-wide singleton"? Do you regard the cluster-wide JNDI tree as a singleton? Surely it is -- there is only one JNDI tree in a cluster. However, in a HA system, the JNDI tree is replicated to each server in the cluster. So in a cluster with n servers, there will be n JNDI trees. Still, we regard the JNDI tree as a singleton.

    So Dieter, if you want a single instance of EJB across a cluster, and in the mean time want it to be high-available, face it: it's not quite possible :)

    However, if you want each server to have just one bean instance, like JNDI tree, I think the solution is entity bean. The implementation depends on how you like your service to be. You may set the isolation level to Serializable if you allow only one concurrent client, or Read-uncommitted if you allow multiple concurrent clients, and any modification to the bean will be avaible to other clients before the end of the transaction. Since your implementation is thread-safe, it's not quite possible for 2 clients to access the same variable, right? Smart containers will not create unnecessary bean instances under this condition.
  13. Dright,

    I cannot understand - you can always have centric JNDI location that could be accessed by all components of the cluster. I am not sure that it's good practice to cluster JNDI - what for???

  14. alex,

    why i'm thinking about the home interface: how can i have my singleton work together with distributed transactions, if i don't use a j2ee component (ejb, or home), and simply bind an object into jndi? I prefer container managed transactions, so my object must be more than only in jndi, the container must be aware of it.
    Why is the home interface not a good idea? In fact, the object i'm talking about is "kind of" home-like. The only thing weird, is i won't use it to create/find ejb's, only to access home methods.
    So still i wonder how a home object behaves when concurrent clients access it. Are they serialised? Or must home objects be thread safe? Or are there many home instances?
  15. Dieter,

    As I mentioned above, you can always wrap your singleton object calls with stateless session bean calls and control transactions via session beans. That should work fine in case if you use CTD.

  16. I thought you meant transaction isolation levels - these are different from transaction attribute. You could just wrap the calls to your singleton in stateless session bean methods and use transaction attributes on them, if you definetely support transaction management in your singleton.