这篇文章作为日常技术问题分析诊断的一下思路记录, 方便后续进一步归纳整理.
- [APP: Service Bus JMS Reporting Provider] [partition-name: DOMAIN] [tenant-name: GLOBAL] An error occurred while inserting data into the Reporting Table with a batch update
- ORA-01461: can bind a LONG value only for insert into a LONG column
注: 首先看 log 日志基本是说说朝 JMS Report 日志表里面插入数据的时候出现了超长的情况, 这个情况是应用层在朝数据库进行 BatchUpdate 的时候报出, 对应到数据库的 ORA-01461 错误. 看了初步日志分析, 按道理对于 OSB 和 JMS 自己的日志处理逻辑应该对超长进行控制, 很难了解到为何会出现超长的情况.
根据日志分析, 进一步搜索也来源于两个线索, 第一个是 OSB JMS Reporting Table, 第二个是 ORA-01461 的数据库异常.
对于数据库 ORA 异常, 参考 https://blog.csdn.net/bisal/article/details/39545463 说法, 即:
当连接 UTF8 字符集的数据库时, 所有字符长度需要乘 3, 因为这是这种字符集的数据需要占据的空间. VARCHAR2 类型的最大长度是 4000 字节, 任何更大的存储值都会作为 LONG 来看待. 运行时不会检查列的实际内容. 即使 VARCHAR2(2000) 列仅包含一个字符, 它也会按照 LONG 处理, 就像使用了一个包含 1 个字符的 LONG 字段. 如果有一个这样的列, 再加上一个 LONG 列, 或者有两个或更多这样的列, 数据库会认为你正在绑定两个 LONG 列. 因此就会报这种错误.
另外一种说法是估计你的表中有定义超过 2000 的字符字段. 对于 gbk 和 utf-8 字符集 oracle 在存储时, 对于一个字符需要 2 个或 3 个字节的存储空间, 其实该字段的 data_length 为其 2 倍或 3 倍长. 这种情况下 oracle 会把 data_length 长度超过 4000 的当做 LONG 型处理, 插入数据时相当于操作 LONG 字段, 所以报错.
网上总结导致 ORA 这个错误的原因主要有三个:
1, 插入到字符串长度大于 4000 字节.
2, 插入到表中的记录的某个字段数据的实际长度大于 2000 个字节 (如果是 UTF-8, 则是 1333 个字节); 或者是插入的记录中有两个或两个以上长度大于 2000 字节的字符串.
3, 数据库与客户端的 JDBC 驱动不匹配.
思考了下, 突然想到是否和我们动过 Oracle 日志表的字段长度导致的? 由于在前面测试的时候发现会报出插入 Oralce 日志表的数据字段超长的错误, 因此我们调整了 Oralce 一个日志表的 Error_Reason 和 Error_Detail 的字段长度到 4000 字节, 而这正符合第 1 个错误原因, 所以间接导致了这个日志错误. 但是我们如果不修改也会报插入日志超长的错误, 而对于 Log 记录本身并没有记录到究竟是什么日志记录导致了超长? 所以也导致这个问题很难进一步进行查询.
接着我们看 OSB 层的日志信息, 用 An error occurred while inserting data into the Reporting Table with a batch update 这个关键字进一步搜索, 可以查到类似的信息如下:
- Caused by: java.lang.RuntimeException: [OSB-Reporting:473522]An error occurred while inserting data into the Reporting Table with Batch Update {0}
- Caused by: java.sql.BatchUpdateException: ORA-12899: value too large for column "MYSCHEMA"."WLI_QS_REPORT_ATTRIBUTE"."MSG_LABELS" (actual: 2053, maximum: 2048)
这个也就是我前面说的, 我们对 Oracle 日志表的 ERROR_DETAILS, 由于修改到了 4000, 导致在超长的时候报出了上面的新的 ORA-01461 的错误, 但是本质还是日志表超长. 这个地方给我一个警示, 还是尽量不能去动 Oralce 本身的系统日志表, 虽然暂时解决了问题, 但是后续暴露出来的异常将会很难进行进一步跟踪.
这个问题找到的线索如下地址, 但是还未彻底解决:
https://support.oracle.com/knowledge/Middleware/1925368_1.html
这篇文章估计要有 Oracle 的社区账号用户才能够登录查看了. 具体的原因还需要进一步的分析.
来源: http://www.tuicool.com/articles/FvIZzab