Cannot enqeue LOBs bigger than 2000 bytes as buffered message into Oracle AQ

323 Views Asked by At

I'm trying to enqueue a JMS-Bytes-Message (AQ$_JMS_BYTES_MESSAGE) as buffered message into a Oracle AQ and reading it with Java JMS. To send messages, I'm using following PL/SQL code:

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;
/

It works fine as long the paylod is not bigger than 2000 characters. As soon the payload is bigger than 2000 chars (like 2001) I receive following SQL error: ORA-25293: Lob attributes must be null for buffered operations.

When setting the AQ delivery mode from DBMS_AQ.BUFFERED to DBMS_AQ.PERSISTENT it works fine with any size.

According to Oracle documentation (Enqueuing Buffered Messages) it is stated:

The queue type for buffered messaging can be ADT, XML, ANYDATA, or RAW. For ADT types with LOB attributes, only buffered messages with null LOB attributes can be enqueued.

The used type is obviously a ADT (JMS types).

Does anyone know a solution for sending buffered JMS messages over Oracle AQ?

1

There are 1 best solutions below

0
tafli On

I just had a look at the spec of aq$_jms_bytes_message. In there it is stated that

set_bytes sets payload in RAW into bytes_raw if the length of payload is <= 2000, otherwise into bytes_lob.

According to this comment, it is not possible to send JMS messages larger than 2000 bytes as buffered AQ message.

Together with the documentation quote mentioned in my question and this comment, it is clear, why I receive a ORA-25293 exception.