代码之家  ›  专栏  ›  技术社区  ›  Synesso

Oracle高级队列中无关消息的选择性出列

  •  2
  • Synesso  · 技术社区  · 14 年前

    这个问题是指在 Oracle流高级队列 .

    我需要确保按顺序处理彼此相关的消息。

    例如,假设队列中的四条消息具有一个名为事务引用(txn_ref)的业务相关字段,其中两条消息(1,3)属于同一事务(000001):

    id | txn_ref | 
    ---+---------+
     1 | 000001  |
     2 | 000002  |
     3 | 000001  |
     4 | 000003  |
    

    另外,假设我正在运行4个希望从此队列中出列的线程/进程。应出现以下情况:

    1. 线程1出列消息1
    2. 线程2出列消息2
    3. 线程3出列消息4(因为消息3与1和1相关,尚未完成)。
    4. 线程4阻止等待消息
    5. 线程1为消息1提交其工作
    6. 线程4(或线程1)将消息出列3。

    我最初的想法是,我可以通过一个出列条件来实现这一点,在这个条件下,所有具有相同txn_ref的消息的enq_时间(enqueue时间)不迟于任何其他enq_时间。但我的问题是,如何引用我尚未选择的消息的txn_ref,以便选择它。例如

    // Java API
    String condition = "ENQ_TIME = (select min(ENQ_TIME) from AQ_TABLE1 where ??";
    dequeueOption.setCondition(condition);
    

    有没有可能实现我在这里想要的?

    2 回复  |  直到 14 年前
        1
  •  2
  •   No AI now No AI ever    14 年前

    要回答您的直接问题,可以使用 correlation 字段(称为 CORRID 在表中),这是为此目的而设计的。

    所以,在排队的时候,你可以用 AQMessageProperties.setCorrelation() 方法,以txn_-ref值作为参数。那么,在你的情况下,你会这样做:

    // Java API
    String condition = "tab.ENQ_TIME = (select min(AQ_TABLE1.ENQ_TIME) from AQ_TABLE1 self where tab.CORRID=AQ_TABLE1.CORRID)";
    dequeueOption.setCondition(condition);
    
        2
  •  1
  •   No AI now No AI ever    14 年前

    如果可能,您可以尝试使用消息组的策略。这个 Oracle Documentation 简单描述一下,但我发现 this Toad World article 更有用。基本上,将队列表设置为将同时提交的所有消息视为一个“组”。出列时,一次只能有一个用户从“消息组”中出列。

    推荐文章