gpt4 book ai didi

java - 奇怪的 session 行为..!!在运行时更改用户对象属性

转载 作者:行者123 更新时间:2023-12-02 07:19:56 24 4
gpt4 key购买 nike

在我们的 Web 应用程序中测试并发访问时,我们在跟踪 session 行为时遇到了一些困难。

假设我们有三个不同的用户,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

有人可以告诉我此 session 行为的原因或者我如何同步它吗?

我注意到一件事:如果用户 A 登录并执行某些搜索操作,并且如果用户 B 同时登录,则 userObj A 将更改为 userObj B。

与应用服务器设置有关吗?仅在进行身份验证时才会发生这种情况。

最佳答案

我想详细了解您如何执行搜索操作以及您在什么时候在 ThreadLocal 对象 (CONTEXT_HOLDER) 中设置了 UserObj。

我们必须记住,ThreadLocal 是线程范围的,而不是 session 范围的。这意味着当且仅当设置该对象的线程与请求该对象的线程相同时,ThreadLocal 中的设置对象才是相同的。

我最初的理论是搜索操作是在同一 session 中执行的,但不是在同一线程上执行的。一个简单的场景如下:

  • UserA 使用线程 A 登录。UserA 使用线程 A 存储在 CONTEXT_HOLDER 中。
  • UserB 使用线程 B 登录。UserB 使用线程 B 存储在 CONTEXT_HOLDER 中。
  • UserC 使用线程 C 登录。UserC 使用线程 C 存储在 CONTEXT_HOLDER 中。
  • 过了一会儿,UserA 执行搜索操作。服务器使用线程 A 执行操作(幸运的是)。ThreadLocal 返回 UserA obj,这是正确且符合预期的!
  • 过了一会儿,用户A再次执行搜索操作。这次,(不幸的是)服务器使用线程 C 执行操作(呃哦!)。 ThreadLocal将返回UserC,因为线程C用于执行搜索操作。(另一方面,如果线程B用于搜索操作,则ThreadLocal将返回UserB)

上面的场景过于简单化,假设服务器仅使用三个线程。但我确实希望它能解释您如何获取不同的 UserObj 对象。如果我上面描述的就是您所遇到的情况,我认为您还会时不时地收到 NULL 值(遇到这种情况的频率取决于服务器使用的总线程数)。原因是 ThreadLocal 如果当前未设置则返回初始值(根据上面的代码,该值为 null)。

因此,解决您问题的方法是确保您在同一线程中执行以下操作:

  • 在 ThreadLocal 中设置 UserObj
  • 执行搜索操作并在 ThreadLocal 中获取 UserObj

如果您希望我能为您提供示例代码,请告诉我。

关于java - 奇怪的 session 行为..!!在运行时更改用户对象属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14377055/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com