gpt4 book ai didi

java - JMS MessageDriven bean - 如何同步线程?

转载 作者:行者123 更新时间:2023-11-30 08:04:43 25 4
gpt4 key购买 nike

尽管消息驱动 bean 是基于异步逻辑的,但我有以下场景:

  1. 2 个包含用户凭据的领域(jdbc 和 ldap)
  2. 当用户在表单中输入用户名和密码时,它会尝试在两个领域(jdbc 和 ldap)中进行身份验证
  3. 对于每次尝试登录的领域,我都会使用 JMS 发送一条消息来记录它

我的问题在于 onMessage(Message message) 重写方法。

考虑下面的 JMS 消息 Bean 的 Java 伪代码:

public void onMessage(Message message){
String username = (cast message to Map and get username);
Login login = (Login)loginDAO.filter( queryByUsername, username );
if( login == null ){
Creates a new entry at database for 'username'
}else{
Uses 'username' already created
}
}

现在我的问题场景:

  1. 我在表单中输入了用户名和密码,然后按“登录”
  2. 尝试登录 JDBC 并触发 JMS 进行记录
  3. 尝试登录 LDAP 并触发 JMS 进行记录
  4. onMessage 几乎同时收到 2 条消息(第 2 条和第 3 条)
  5. 消息 1 创建一个新用户,因为数据库中不存在该用户
  6. 消息 2 还创建一个具有相同用户名的新用户

我需要消息 2 使用消息 1(如果逻辑)上创建的用户(其他逻辑),但我认为它(消息 2)太快,以至于条目尚未在数据库中持久化,并且两条消息都被捕获“如果逻辑”。

如果我的主题令人困惑且不合适,请提出建议。

[编辑]到目前为止我所得到的:

服务器中有一个 MessageDriven Beans (MDB) 池,对于 2 条消息到达,您将同时运行 2 个 MDB,因此您将保留相同的信息 2 次。

我在注释消息驱动 Bean 中使用了名为 maxSession 的属性

@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")

现在我的池中只有一个 MDB,并且我在负责检查“用户名”登录审核的所有逻辑的方法中放置了一个 SYNCHRONIZED。

[编辑2]根据尼古拉斯的观察,如下:

删除了池限制,并创建了一个用于数据库检查的静态方法(检查用户名是否存在或需要创建和保留)。

静态,因为它需要与 MDB 的所有实例共享,并且还需要同步以避免在数据库中重复条目。

谢谢

最佳答案

在不知道这段代码实际上应该做什么的情况下,MDB 似乎仍然是实现同步的错误位置。据推测,您的用户数量是有限的,并且每个用户将处理多条消息。通过将 MDB 池限制为一个实例,您将严重限制 MDB 处理器上的吞吐量。

我建议您不要尝试在 MDB 中同步,而是考虑在用户名持久性机制中实现同步,或者如您在代码中所描述的那样:

Creates a new entry at database for 'username'
这样,可以同时处理多条消息,但它们会短暂阻塞,而运气决定哪个线程保存用户名(一个将保存它,然后获取它,其他线程将等待然后获取它)。之后,您将不会多次阻止单个用户名,并且可以运行完整的 MDB 池。

关于java - JMS MessageDriven bean - 如何同步线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31300190/

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