Singleton in the J2EE container...

Discussions

EJB programming & troubleshooting: Singleton in the J2EE container...

  1. Singleton in the J2EE container... (16 messages)

    Hi,

    I am having a problem with the way singleton is behaving in my J2EE container. Here is the scoope:

    I have an MDB calling a method on my Stateless SB. The method on the session bean calls an operation on a singleton object. My Singleton is not caching any state. All the variables are local to the operation. The operation in the singleton is getting the next seq number from the database and inserts a row in a table.

    This runs fine if I send one message to my MQ which invokes the MDB however if I send 100 messages to the MQ which invokes many instances of the MDB then 20 or more of these messages will end up with primary key violation.

    Since every MDB runs in its own thread in this case we probably have 100 or less threads running at the same time, each thread is using its on instance of Stateless SB but they all sharing the same instance of the Singleton object. Having said that, why do I get the primary key violation? I thought each thread executes an operation on the Singleton own its local stack?

    Again our singleton does not have any state and the operations are all none-static with the exception of the getInstance() operation.

    We are using BEA 8.2 with Oracle 9i.

    Do I need to synchronize the calls to the Singleton? but that would violate the EJB spec. Please help.

    Thanks in advance.

    Threaded Messages (16)

  2. Singleton in the J2EE container...[ Go to top ]

    I wonder if you have any non static field that you have declared at class level.
  3. Singleton in the J2EE container...[ Go to top ]

    < 
    >>
    Hi,

    Not in the Singleton class nor in the SB.
  4. Singleton in the J2EE container...[ Go to top ]

    Is your method, which will get the next seq number from the database synchronized?
  5. Singleton in the J2EE container...[ Go to top ]


    >>

    Hi,

    The method that gets the next seq number from the database is not synchronized. This method is part of the Singleton class. It's my understanding that all the threads that executing an operation on a Singleton object have their own copy of the local variables thus there is not reason for synchronization unless I have been mislead. Please confirm.

    Thanks
  6. Singleton in the J2EE container...[ Go to top ]

    There will be one and only one instance of that class during the life cycle of the application. Local variables are like the other local variables, there is no any difference between a singleton’s method and any other methods. The other point is how you call to get the next number from database, it is possible that when you call to get the next sequence, before committing the transaction, for example, another thread will call and get the same number from the sequence.
  7. Singleton in the J2EE container...[ Go to top ]

    <
    Hi Kambiz,

    This actually confirms my understandings of Singleton. Regarding your comment about threads getting the same seq number, how could 2 threads get the same seq number?

    As you mentioned each thread has its own copy of the local variables such as database connection, the seq number and so on. They each making a call to the Oracle nextVal() function and obtain a new seq number then each thread insert a new row to the database and commit.

    Thanks,
    Tony.

    SB
  8. Singleton in the J2EE container...[ Go to top ]

    Is there any reason that:

    1. You get the next sequence number
    2. Insert the row into the table from the application

    You maybe able to avoid the problem by inserting the row and having a DB Trigger generate the sequence on Insert.

    No singleton no problems.............
  9. Singleton in the J2EE container...[ Go to top ]

    Sohil,

    Our DBA doesn't want us to use triggers. Also we tried No singleton but we still have a problem
  10. Singleton in the J2EE container...[ Go to top ]

    Change DBA
  11. Singleton in the J2EE container...[ Go to top ]

    <i have read somewhere singleton fails when more than one jvm is used. because all jvm has one copy of singleton. so i think, may be for performance issue weblogic will be using more than one jvm to support bean pooling & object management. well i try to find out what peoples say on net and i find couple of suggestion.

    1. I always thought that it was impossible to implement a singleton in J2EE.
    The existence of multiple JVMs in a system, and even multiple class-loaders
    in a single JVM, cause no end of problems.

    A solution that I've heard raised to these problems is to use JNDI to
    register the Singleton, but then anyone who wishes to get access to the
    single instance of the singleton must access JNDI to find it. However, this
    means that a developer could create an instance of the singleton class and
    nothing could stop them.

    Unfortunatly, to correctly implement a singleton is to deny a developer the
    ability of creating instances of a class will-he-nill-he.

    So, with JNDI, an object that would be a singleton could look itself up. If
    it doesn't find itself then it declares itself the singleton and binds
    itself to its name. If it does find itself then we have a problem. In this
    case the instance should delete itself, and return a reference to the real
    singleton. This causes two problems. First, the developer could choose to
    ignore the return value of the method that finds the singleton. Second, for
    a short time two instances of the singleton would exist, and this could
    defeat the singleton.

    So, singletons appear to be impossible. The solution is to have a well-known
    central factory, and to stop objects being created except through that
    factory (private constructors, etc). This may create a bottleneck in ones
    systems though, and would almost certainly not scale too well, becasue the
    factory must sit in a single JVM on a single box. This is almost impossible
    in any system that requires fail-over support.

    Anyway, why would anyone ever need one? An alternative is to provide as many
    objects as the developers want, and to allow them to communicate, and
    synchronise, when necessary.


    2. http://java.sun.com/developer/technicalArticles/Programming/singletons/

    Preet >>

    Hi Preet,

    Actually we have solved the problem by instantiating the object inline with the instance declaration as follow:

    public class xyz{

    private static xyz _instance = new xyz();
    ......

    public xyz getInstance(){return _instance;}

    }
  12. Singleton in the J2EE container...[ Go to top ]

    <http://java.sun.com/developer/technicalArticles/Programming/singletons/Preet >>Hi Preet,Actually we have solved the problem by instantiating the object inline with the instance declaration as follow:public class xyz{private static xyz _instance = new xyz();......public xyz getInstance(){return _instance;}}
    Hi Blair,
    as per my understanding if two JVM are used they both will have different copies of that object and that method can be called form two location..
    can you please elabote how two JVM works on heap memory ?
  13. Singleton in the J2EE container...[ Go to top ]

    Tony:

    You are right. You need to synchronize. These are two different things that we are talking about:

    (1) Having only one instance
    (2) Being executed by only one thread at a time.

    Singleton is (1) and NOT (2). It is possible that more than one caller is holding a handle to a singleton though there is only one instance. You really cannot figure out how many callers have handle to a singleton and nothing prevents all the callers to execute a method call unless that method is synchronized. ALL METHODS OF A SINGLETON MUST BE THREAD-SAFE (Again, that does not necessarily mean synchronized - depends on the scenario)

    -Sanjay
  14. HI,
    i have read somewhere singleton fails when more than one jvm is used. because all jvm has one copy of singleton. so i think, may be for performance issue weblogic will be using more than one jvm to support bean pooling & object management. well i try to find out what peoples say on net and i find couple of suggestion.

    1. I always thought that it was impossible to implement a singleton in J2EE.
    The existence of multiple JVMs in a system, and even multiple class-loaders
    in a single JVM, cause no end of problems.

    A solution that I've heard raised to these problems is to use JNDI to
    register the Singleton, but then anyone who wishes to get access to the
    single instance of the singleton must access JNDI to find it. However, this
    means that a developer could create an instance of the singleton class and
    nothing could stop them.

    Unfortunatly, to correctly implement a singleton is to deny a developer the
    ability of creating instances of a class will-he-nill-he.

    So, with JNDI, an object that would be a singleton could look itself up. If
    it doesn't find itself then it declares itself the singleton and binds
    itself to its name. If it does find itself then we have a problem. In this
    case the instance should delete itself, and return a reference to the real
    singleton. This causes two problems. First, the developer could choose to
    ignore the return value of the method that finds the singleton. Second, for
    a short time two instances of the singleton would exist, and this could
    defeat the singleton.

    So, singletons appear to be impossible. The solution is to have a well-known
    central factory, and to stop objects being created except through that
    factory (private constructors, etc). This may create a bottleneck in ones
    systems though, and would almost certainly not scale too well, becasue the
    factory must sit in a single JVM on a single box. This is almost impossible
    in any system that requires fail-over support.

    Anyway, why would anyone ever need one? An alternative is to provide as many
    objects as the developers want, and to allow them to communicate, and
    synchronise, when necessary.


    2. http://java.sun.com/developer/technicalArticles/Programming/singletons/

    Preet
  15. Singleton in the J2EE container...[ Go to top ]

    <
    You are right. You need to synchronize. These are two different things that we are talking about:

    (1) Having only one instance
    (2) Being executed by only one thread at a time.

    Singleton is (1) and NOT (2). It is possible that more than one caller is holding a handle to a singleton though there is only one instance. You really cannot figure out how many callers have handle to a singleton and nothing prevents all the callers to execute a method call unless that method is synchronized. ALL METHODS OF A SINGLETON MUST BE THREAD-SAFE (Again, that does not necessarily mean synchronized - depends on the scenario)

    -Sanjay >>
    Hi Sanjay,

    We run a little test last night. We changed the Singleton class to a none singleton so each thread will have a new instance to this class. We then run the code and the primary key violation problem still exists.

    We use the SpringFramework to handle all the database calls, so I think there might be a problem with the Spring Framework.

    Thanks,
    Tony.
  16. Singleton in the J2EE container...[ Go to top ]

    Tony,
    1)Are you sure you have only one instance of the class available?
    2)As my understanding, you have this problem when you want to insert a lot of object into database. Can you just synchronize the method and run it and see the result?
    3)How do you get the next sequence number from database?
    4)I didn’t understand why you are instantiating the object inline.
  17. Do you use Oracle Sequences?
    They assure you that no one number is repeated with .nextVal()...

    you just can simply put the sequence.nextVal() in your insert sentence:
    INSERT INTO ... VALUES (SQENCE.NEXTVAL(), ...);