在我们的Web应用程序中测试并发访问时,我们在跟踪会话行为时遇到了一些困难。
假设我们有三个不同的用户,A,B和C.
我们使用这三个用户登录到具有三个不同浏览器的应用程序,然后在运行时我的用户对象从B变为A或B变为C或C变为A,但这是随机发生的。
我的UserContextHolder类是:
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();
}
}
我正在使用Hibernate进行ORM和Spring MVC
有人可以告诉我此会话行为的原因或我如何同步它吗?
我注意到一件事:如果用户A已登录并进行一些搜索操作,并且如果用户B同时登录,则userObj A将更改为userObj B.
是否与应用程序服务器设置有关?只有在进行身份验证时才会发生这种情况。
答案 0 :(得分:2)
我想了解更多关于您如何执行搜索操作以及您在ThreadLocal对象(CONTEXT_HOLDER)中设置UserObj的更多信息。
我们必须记住,ThreadLocal是线程作用域,不是会话作用域。这意味着ThreadLocal中的set对象是相同的当且仅当设置对象的线程与请求它的线程相同时。
我的初步理论是搜索操作在同一会话中执行,但不在同一个线程上执行。一个简单的场景如下:
假设服务器只使用了三个线程,上面的场景过于简化了。但我希望它能解释你如何获得不同的UserObj对象。 如果我上面描述的是您正在经历的内容,我认为您也会不时收到NULL值(遇到的频率取决于服务器使用的总线程数)。原因是如果当前没有设置ThreadLocal返回初始值(根据上面的代码为null)。
因此,解决您的问题的方法是确保您在相同的帖子中执行以下操作:
如果您希望我能为您提供示例代码,请告诉我。