2012-03-07 102 views
3

首先,我正在寻找解决此问题的不同方法。数据库中的队列管理

我在我们的应用程序中有一个队列在数据库表中维护。 有一个预定的处理器,它将查看队列并根据记录上的STATUS字段提取记录。 它处理这些记录,并成功从表中删除记录。

问题是我的应用程序是聚簇的。因此,将有几个预定处理器的实例,将拉出相同的记录,然后处理它们...

要解决这个问题,我遵循的方法是 我更新记录之前它的状态(从PENDING到WORKING),并且还在表格的实体映射上添加了一个版本,因此动作的顺序为:

1)查询表中的PENDING记录。 2)更新状态为WORKING。 (如果处理器的另一个实例在某人已更新记录时尝试更新它,则会发出异常,因此将转移到下一条记录) 3)成功。删除记录,否则将其更新回PENDING。

现在,这样做会很解决问题,但不很喜欢这个主意......

想找出谁面临着类似的问题,人们已经解决了。

我有另一种方法来解决这个问题,因为相同的应用程序填充表,将它分配给填充它的主机,并且该特定tomcat上的计划处理器仅查找该主机的记录。基本上要尽量减少第一个解决方案将会发生的颠簸。

它是一个Spring 3.0.5和Hibernate应用

+0

你看了看:ZeroMQ还是Apache Kafka? – eSniff 2012-03-07 00:35:07

回答

2

这是很普遍的问题。你可以从不同的方式解决它:

  • 拥有通过分配新的状态+乐观锁定当前处理的记录。这是你的方法,它会起作用,但如果当前正在处理某个节点的节点死亡,则必须记住清理表格。

  • 同上,但悲观锁定 - 只有一个节点可以访问整个队列 - 如果有很多节点,并且经常发生乐观锁失败

  • 外部/全局锁可能是一个更好的方法表一次。您可以使用表级锁定来阻止所有其他节点或一些节点。

  • 在队列表中放置新记录时,随机化并将其分配给给定节点,以便其他节点无法处理它。不要走这条路,维护噩梦,例如当添加或删除节点时。

  • 使用,它会自动聚集作业并在一个节点上运行它们。它使用类似于上面的技术(悲观锁定在共享数据库上)

  • ...或者只是使用普通的JMS提供程序,数据库并不真正用作队列...