JOHND
JOHND

Reputation: 2767

Weird session behavior..!! changing user object properties at runtime

While testing concurrent access in our web application we are having some difficulty tracing session behavior.

Say we have three different users, A, B, and C.

We are logging in to the application with three different browsers with these three users then at run time my user object is changing from B to A or B to C or C to A, but this is happening randomly.

My UserContextHolder class is :

public final class UserObjContextHolder {
    private static final ThreadLocal<UserObj> CONTEXT_HOLDER = new ThreadLocal<UserObj>();

    private UserObjContextHolder() {
    }

    public static void setUserObj(UserObj userObj) {
        CONTEXT_HOLDER.set(userObj);
    }

    public static UserObj getUserObj() {
        return CONTEXT_HOLDER.get();
    }

}

I am using Hibernate for ORM and Spring MVC

Can anybody tell me reasons for this session behavior or how I can synchronize it?

I noticed one thing: if User A is logged in and doing some search operation and if User B logs in at the same time then userObj A is changing to userObj B.

Is it related to Application server setting? This happens only while doing authentication.

Upvotes: 0

Views: 126

Answers (1)

elvin harley aquino
elvin harley aquino

Reputation: 48

I would like to know more on how you have performed your search operation and at what point you have set the UserObj in your ThreadLocal object (CONTEXT_HOLDER).

We must remember that ThreadLocal is thread scoped and not session scoped. This means that the set object in the ThreadLocal is the same if and only if the thread that set the object is the same as the thread who requested it.

My initial theory would be the search operation is performed in the same session but not on the same thread. A simple scenario would like be below:

  • UserA logs in using Thread A. UserA is stored in the CONTEXT_HOLDER using Thread A.
  • UserB logs in using Thread B. UserB is stored in the CONTEXT_HOLDER using Thread B.
  • UserC logs in using Thread C. UserC is stored in the CONTEXT_HOLDER using Thread C.
  • After a while UserA performs search operation. Server executes the operation (luckily) using Thread A. ThreadLocal returns UserA obj which is correct and expected!
  • Again, after a while, User A performs search operation. This time, (unfortunately) the server executes the operation using Thread C (uh-oh!). ThreadLocal will return UserC since Thread C was used to execute the search operation. (On the other hand, if Thread B was used in the search operation, UserB will be returned by ThreadLocal)

Above scenario was over-simplified, assuming only three threads are used by the server. But I do hope it explains how you are getting different UserObj objects. If what I described above is what you are experiencing, I think you are also receiving NULL values from time to time (frequency of this encountered depends on the total threads used by the server). The reason is that ThreadLocal returns the initial value if it is not currently set (which is null based on your code above).

So a solution to your problem is to ensure you perform the following in the same thread:

  • Set UserObj in your ThreadLocal
  • Perform search operation and getting UserObj in your ThreadLocal

If you wish I can give you a sample code for this, just let me know.

Upvotes: 2

Related Questions