【问题标题】:Java - MDB - How to avoid concurrency issueJava - MDB - 如何避免并发问题
【发布时间】:2014-03-02 19:24:19
【问题描述】:

我们实现了 MDB,它接受用户输入和并行处理。我们对用户数据进行了限制检查(例如用户可以拥有的电话号码数量)。

我面临的问题是两个不同的线程获取相同用户的数据并进行处理。第一个线程很好,它检查限制并将手机正确添加到用户配置文件中。第二个线程也做同样的事情。但是限制检查发生在第一个线程提交事务之前,因此限制检查通过了。但它超过了极限。

有什么办法可以解决吗?让同一线程挑选一个用户的数据很好。但我不知道该怎么做。

请帮忙。提前致谢。

编辑:我还想传达一件事。在不同节点运行时会出现此问题。

【问题讨论】:

  • 您遇到了并发问题而不是并行问题。你需要某种方式来控制谁在什么时候得到什么。如果没有更多信息,我就无法添加更多内容。
  • @edharned 谢谢,我已经相应地更新了问题
  • 看看这个模式:eaipatterns.com/CompetingConsumers.html。考虑一下如果用户空间在服务器之间分配会发生什么。就像,一台服务器处理帐户从 0-5 开始的用户,另一台服务器处理从 6-9 开始的用户。现在您有了 SPOF,但这可以通过使用租约机制来解决,其中每个租约代表一个范围,并且服务器在启动时获取租约。

标签: java concurrency message-queue


【解决方案1】:

这取决于应用服务器、节点数量和应用程序,但以下场景对我来说是可以的:

  • Weblogic 或 JBOSS 支持 订单单位 功能:

Message Unit-of-Order 是 WebLogic Server 的一项增值功能, 启用独立的消息生产者或一组生产者 作为一个,将消息分组到一个单元中 处理订单。这个单一的单元称为顺序单元,并且 要求来自该单元的所有消息按顺序处理 它们的创建顺序。

  • 如果您更新同一条记录,第一个线程获取锁而第二个线程等待事务提交,那么第二个线程应该检查更新(乐观锁),它可以立即退出。

例如。

Thread 1: lastUpd = now() 
Thread 1: UPDATE MYTABLE SET LAST_UPDATE=${lastUpd} WHERE ID=${id}
Thread 2: lastUpd = now()
Thread 2: UPDATE MYTABLE SET LAST_UPDATE=${lastUpd} WHERE ID=${id} //remain locked
Thread 1: a lot of work ...
Thread 1 COMMIT
Thread 2: a lot of work ...
Thread 2: lastUpd2= SELECT LAST_UPDATE MYTABLE WHERE ID=${id}
Thread 2: IF lastUpd2!= lastUpd ROLLBACK

【讨论】:

  • 我不知道如何实现订单单元功能。能否请您提供一些链接或信息?谢谢。
  • 什么都不需要实现,只需要配置weblogic,把uuid放在消息头上:docs.oracle.com/cd/E15051_01/wls/docs103/jms/uoo.html
  • 我将以编程方式使用,因为相同的队列也用于不同的消息。谢谢
  • 我试过了,它似乎工作正常,没有重复的问题。但是具有相同 UOO 的消息在集群环境中会发送到不同的节点。是预期的吗?
猜你喜欢
  • 2011-01-30
  • 2015-05-09
  • 1970-01-01
  • 2012-04-09
  • 2023-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多