DBMS_AQ.ENQUEUE_ARRAY 在 Oracle JDBC 驱动程序中导致内部 ArrayIndexOutOfBoundsException
DBMS_AQ.ENQUEUE_ARRAY causes internal ArrayIndexOutOfBoundsException in Oracle JDBC driver
鉴于:
create TYPE things IS VARRAY(1) OF THING_TYP NOT NULL;
和一个 Oracle AQ 队列 table,以及一个队列 FOO_BAR
,使用 JDBC CallableStatement 调用 DBMS_AQ.ENQUEUE_ARRAY
导致 ArrayIndexOutOfBoundsException
深入内部ojdbc.jar 内的专有 Oracle 代码。下一个查询导致协议错误 - 似乎之前的错误导致驱动程序中的协议读取代码不同步,因为它没有完成。
但是,这种类型的调用最初在 SQL Developer 中有效!那么也许队列或队列 table 进入了错误状态?
PL/SQL 的一个简单的、未参数化的示例如下。 运行 这与最初工作的调用相同 - 似乎也在 SQL Developer 中产生相同的症状。虽然 SQL 开发人员没有向用户显示 ArrayIndexOutOfBoundsException - 它只是没有显示任何输出 - 在日志页面上有异常堆栈跟踪的片段,并且它确实显示了后续的协议错误,当我尝试刷新左侧树视图中的队列列表。
DECLARE
enqueue_options DBMS_AQ.enqueue_options_t;
msg_prop_array DBMS_AQ.message_properties_array_t;
msg_prop DBMS_AQ.message_properties_t;
payload_array things := things(THING_TYP(IDENTIFIERVALUE => 'abc'));
msgid_array DBMS_AQ.msgid_array_t;
retval PLS_INTEGER;
BEGIN
msg_prop_array := DBMS_AQ.message_properties_array_t(msg_prop);
retval := DBMS_AQ.ENQUEUE_ARRAY(
queue_name => 'FOO_BAR',
enqueue_options => enqueue_options,
array_size => 1,
message_properties_array => msg_prop_array,
payload_array => payload_array,
msgid_array => msgid_array);
END;
我如何尝试诊断队列可能出现的问题?
(一个可能的线索是,我在之前尝试调用同一存储过程时创建并删除了一些临时 VARRAY 类型 - 由一条错误消息提示,指出消息数组的大小必须与消息属性数组。鉴于我的数组将具有不同的大小,我决定每次都创建临时 VARRAY 类型并在加载数据后删除它们。但这可能无关紧要,因为 VARRAY 只能用作临时类型存储过程中用于将数据传输到队列中的类型 - 它们不应用作队列的一部分或队列本身 table。)
更新: 看起来 没有 最初工作,只是 似乎 像它做了。创建一个新队列 table 并在该队列 table 中创建一个新队列,然后 运行 PL/SQL 针对新队列,导致同样的问题 - 没有输出,并且然后当我尝试刷新队列列表时出现协议错误。
该队列是一个多消费者队列,不知何故我未能设置订阅 - 然后我在创建新队列时忘记再次设置订阅以查看是否可以重现错误。
在新队列上设置订阅使 PL/SQL 工作:
PL/SQL procedure successfully completed.
鉴于:
create TYPE things IS VARRAY(1) OF THING_TYP NOT NULL;
和一个 Oracle AQ 队列 table,以及一个队列 FOO_BAR
,使用 JDBC CallableStatement 调用 DBMS_AQ.ENQUEUE_ARRAY
导致 ArrayIndexOutOfBoundsException
深入内部ojdbc.jar 内的专有 Oracle 代码。下一个查询导致协议错误 - 似乎之前的错误导致驱动程序中的协议读取代码不同步,因为它没有完成。
但是,这种类型的调用最初在 SQL Developer 中有效!那么也许队列或队列 table 进入了错误状态?
PL/SQL 的一个简单的、未参数化的示例如下。 运行 这与最初工作的调用相同 - 似乎也在 SQL Developer 中产生相同的症状。虽然 SQL 开发人员没有向用户显示 ArrayIndexOutOfBoundsException - 它只是没有显示任何输出 - 在日志页面上有异常堆栈跟踪的片段,并且它确实显示了后续的协议错误,当我尝试刷新左侧树视图中的队列列表。
DECLARE
enqueue_options DBMS_AQ.enqueue_options_t;
msg_prop_array DBMS_AQ.message_properties_array_t;
msg_prop DBMS_AQ.message_properties_t;
payload_array things := things(THING_TYP(IDENTIFIERVALUE => 'abc'));
msgid_array DBMS_AQ.msgid_array_t;
retval PLS_INTEGER;
BEGIN
msg_prop_array := DBMS_AQ.message_properties_array_t(msg_prop);
retval := DBMS_AQ.ENQUEUE_ARRAY(
queue_name => 'FOO_BAR',
enqueue_options => enqueue_options,
array_size => 1,
message_properties_array => msg_prop_array,
payload_array => payload_array,
msgid_array => msgid_array);
END;
我如何尝试诊断队列可能出现的问题?
(一个可能的线索是,我在之前尝试调用同一存储过程时创建并删除了一些临时 VARRAY 类型 - 由一条错误消息提示,指出消息数组的大小必须与消息属性数组。鉴于我的数组将具有不同的大小,我决定每次都创建临时 VARRAY 类型并在加载数据后删除它们。但这可能无关紧要,因为 VARRAY 只能用作临时类型存储过程中用于将数据传输到队列中的类型 - 它们不应用作队列的一部分或队列本身 table。)
更新: 看起来 没有 最初工作,只是 似乎 像它做了。创建一个新队列 table 并在该队列 table 中创建一个新队列,然后 运行 PL/SQL 针对新队列,导致同样的问题 - 没有输出,并且然后当我尝试刷新队列列表时出现协议错误。
该队列是一个多消费者队列,不知何故我未能设置订阅 - 然后我在创建新队列时忘记再次设置订阅以查看是否可以重现错误。
在新队列上设置订阅使 PL/SQL 工作:
PL/SQL procedure successfully completed.