Reputation: 2767
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
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:
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:
If you wish I can give you a sample code for this, just let me know.
Upvotes: 2