无法将大于 2000 字节的 LOB 作为缓冲消息排入 Oracle AQ
Posted
技术标签:
【中文标题】无法将大于 2000 字节的 LOB 作为缓冲消息排入 Oracle AQ【英文标题】:Cannot enqeue LOBs bigger than 2000 bytes as buffered message into Oracle AQ 【发布时间】:2020-02-13 13:16:23 【问题描述】:我正在尝试将 JMS-Bytes-Message (AQ$_JMS_BYTES_MESSAGE
) 作为缓冲消息排入 Oracle AQ 并使用 Java JMS 读取它。要发送消息,我使用以下 PL/SQL 代码:
declare
L_JmsMessage sys.AQ$_JMS_BYTES_MESSAGE;
L_EnqueueOptions DBMS_AQ.ENQUEUE_OPTIONS_T;
L_MessageProperties DBMS_AQ.MESSAGE_PROPERTIES_T;
L_MsgId raw(16);
L_Queue varchar2(80) := 'MYQUEUE';
L_Payload blob;
L_CorrId varchar2(100);
dest_offset integer := 1;
src_offset integer := 1;
lang_context integer := 0;
l_warning integer;
begin
L_EnqueueOptions.VISIBILITY := DBMS_AQ.IMMEDIATE;
L_EnqueueOptions.DELIVERY_MODE := DBMS_AQ.BUFFERED;
L_MessageProperties.CORRELATION := L_CorrId;
L_MessageProperties.PRIORITY := 90;
L_MessageProperties.DELAY := DBMS_AQ.NO_DELAY;
DBMS_LOB.createTemporary(L_Payload, true);
DBMS_LOB.ConvertToBlob(L_Payload, createCLOB(2001), DBMS_LOB.LOBMAXSIZE, dest_offset, src_offset, 0, lang_context, l_warning);
dbms_output.put_line('L_Payload length: '|| DBMS_LOB.GETLENGTH(L_Payload));
L_jmsMessage := sys.aq$_jms_bytes_message.construct;
L_jmsMessage.set_type('HttpResponse');
L_jmsMessage.set_bytes(L_Payload);
L_jmsMessage.set_string_property('COMPRESSED', 'false');
DBMS_AQ.ENQUEUE(
queue_name => L_Queue
,enqueue_options => L_EnqueueOptions
,message_properties => L_MessageProperties
,payload => L_jmsMessage
,msgid => L_MsgId
);
dbms_lob.freeTemporary(L_Payload);
end;
/
只要有效载荷不超过 2000 个字符,它就可以正常工作。一旦有效负载大于 2000 个字符(如 2001),我就会收到以下 SQL 错误:
ORA-25293: Lob attributes must be null for buffered operations
.
将 AQ 交付模式从 DBMS_AQ.BUFFERED
设置为 DBMS_AQ.PERSISTENT
时,它适用于任何尺寸。
根据 Oracle 文档 (Enqueuing Buffered Messages) 声明:
缓冲消息的队列类型可以是 ADT、XML、ANYDATA 或 RAW。对于具有 LOB 属性的 ADT 类型,只能将具有空 LOB 属性的缓冲消息入队。
使用的类型显然是 ADT (JMS types)。
有人知道通过 Oracle AQ 发送缓冲 JMS 消息的解决方案吗?
【问题讨论】:
【参考方案1】:我刚刚看了aq$_jms_bytes_message
的规范。里面说
set_bytes 如果有效载荷的长度
根据此评论,无法将大于 2000 字节的 JMS 消息作为缓冲 AQ 消息发送。
连同我的问题中提到的文档引用和此评论,很清楚为什么我会收到 ORA-25293 异常。
【讨论】:
以上是关于无法将大于 2000 字节的 LOB 作为缓冲消息排入 Oracle AQ的主要内容,如果未能解决你的问题,请参考以下文章
WebSocketClient 无法接收大小大于约 16k 字节的消息。抛出 ConnectionLostException