在出队过程中会话终止后 Oracle AQ 消息丢失

发布于 2024-11-25 07:21:28 字数 1538 浏览 3 评论 0原文

我在 Oracle 11g R2 Windows 2008 R2 数据库上遇到 DBMS_AQ.deQueue 问题。当会话出队并在之后(提交或回滚之前)被终止时,特定消息将从队列中永久删除。我希望它仍然在队列中,或者至少在异常队列中。我执行以下步骤进行测试:

  1. 从会话 1 入队,然后提交。 (参见下面的代码)
  2. 从会话 2 出列。(参​​见下面的代码)
  3. 会话 1: select * from MY_Q_T ->我的消息在这里仍然可见。
  4. 会话 2:从 MY_Q_T 选择 * ->我的消息不再可见。
  5. 终止会话 2(出队)会话。
  6. 会话 1:从 MY_Q_T 选择 * ->我的消息不再可见。消息丢失。

这是一个错误吗?由于出队(/可见性)未设置为自主,所以当会话 2 被终止时,我希望消息仍然在队列中。有解决方法的想法吗?

用于入队和出队的代码:

ENQUEUE

declare
    queue_options      DBMS_AQ.ENQUEUE_OPTIONS_T;
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
    message_id         raw(16);
    pl                 MY_PAYLPOAD_T;
begin
    DBMS_AQ.enQueue(queue_name         => 'MY_Q',
                    enqueue_options    => queue_options,
                    message_properties => message_properties,
                    payload            => pl,
                    msgid              => message_id);
end;

DEQUEUE

declare
    queue_options      DBMS_AQ.DEQUEUE_OPTIONS_T;
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
    message_id         raw(2000);
    pl               MY_PAYLPOAD_T;
begin
    DBMS_AQ.DEQUEUE(queue_name         => 'MY_Q',
                  dequeue_options    => queue_options,
                  message_properties => message_properties,
                  payload            => pl,
                  msgid              => message_id);
end;

I have an issue with DBMS_AQ.deQueue on an Oracle 11g R2 Windows 2008 R2 database. When a session does a dequeue and it is killed after that (before a commit or rollback), the particular message is permanently removed from the queue. I would expect it to still be in the queue, or at least be in the exception queue. I perform the following steps to test:

  1. Enqueue from session 1, and commit. (see code below)
  2. Dequeue from session 2. (see code below)
  3. Session 1: select * from MY_Q_T -> my message is still visible here.
  4. Session 2: select * from MY_Q_T -> my message is not visible anymore.
  5. Kill Session 2 (the dequeue) session.
  6. Session 1: select * from MY_Q_T -> my message is not visible anymore. The message is lost.

Is this a bug? Since the dequeue (/visibility) is not set to be autonomous I would expect the message to be still in the queue when session 2 was killed. Any ideas for a workaround?

Code used for enqueue and dequeue:

ENQUEUE:

declare
    queue_options      DBMS_AQ.ENQUEUE_OPTIONS_T;
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
    message_id         raw(16);
    pl                 MY_PAYLPOAD_T;
begin
    DBMS_AQ.enQueue(queue_name         => 'MY_Q',
                    enqueue_options    => queue_options,
                    message_properties => message_properties,
                    payload            => pl,
                    msgid              => message_id);
end;

DEQUEUE:

declare
    queue_options      DBMS_AQ.DEQUEUE_OPTIONS_T;
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
    message_id         raw(2000);
    pl               MY_PAYLPOAD_T;
begin
    DBMS_AQ.DEQUEUE(queue_name         => 'MY_Q',
                  dequeue_options    => queue_options,
                  message_properties => message_properties,
                  payload            => pl,
                  msgid              => message_id);
end;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你列表最软的妹 2024-12-02 07:21:28

你如何终止会话?看起来您刚刚从会话注销,默认情况下会在客户端程序的会话中提交任何打开的事务。
由于出队事务已提交,因此该消息已从队列中消失。

您可以通过在表中插入一行、终止/关闭会话并检查是否添加了该行来验证这一点。

How are you killing the session ? It looks like you are just logging off from the session which defaults to committing any open transactions in the session in your client program.
And since the dequeue transaction is committed, the message is gone from the queue.

You can verify this by inserting a row into a table, kill/close your session and check if the row is added.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文