【发布时间】:2014-11-17 06:20:27
【问题描述】:
在一个软件项目中,我们偶然发现了一个错误,我们将 Java 中的一个大数字(17 位)插入到 Oracle DB 过程中。这个数字有时会改变它的值+1或-1。有时保持不变。我们检查了 oracle DB 驱动程序调试日志,发现它打印了正确的数字。 我们还尝试在每个请求之间重新启动 Java 应用程序服务器,以消除奇怪的缓存错误。仍然得到相同的结果。
任何想法为什么会发生这种情况?
代码如下:
// Datasource configuration
<New class="oracle.jdbc.pool.OracleDataSource">
<Set name="DriverType">thin</Set>
<Set name="URL">jdbc:oracle:thin:@xxxx</Set>
<Set name="User">uuuu</Set>
<Set name="Password">pppp</Set>
</New>
// JAVA
SimpleJdbcCall testMsg = new SimpleJdbcCall(dataSource).
withSchemaName(schema).
withCatalogName(catalog).
withProcedureName("test_msg");
public void testMessage(Long n) {
testMsg.execute(n, n, n.toString());
}
// PL_SQL
procedure test_msg(
i integer,
n number,
v varchar2
) is
log_prfx log_pkg.t_log_prfx := 'test_msg: ';
begin
g_log.log_debug(log_prfx||'i='||to_char(i));
g_log.log_debug(log_prfx||'n='||to_char(n));
g_log.log_debug(log_prfx||'v='||v);
end test_msg;
现在打电话
testMessage(10000000000000005L);
testMessage(10000000000000007L);
testMessage(10000000000000009L);
最终得到类似
的日志test_msg: i=10000000000000005
test_msg: n=10000000000000005
test_msg: v=10000000000000005
test_msg: i=10000000000000008
test_msg: n=10000000000000008
test_msg: v=10000000000000007
test_msg: i=10000000000000008
test_msg: n=10000000000000008
test_msg: v=10000000000000009
我们正在使用的版本。
- 春季 3.2.11
- Oracle 驱动程序 ojdbc7_g-12.1.0.2(我们还使用 11.2.0.4 进行了测试)
- Oracle DB 版本为 12.1.0.1.0
- Jetty 9.2.2 和 JBoss 7(两者都出现了相同的行为)
【问题讨论】:
-
我不确定它是否有帮助,但也许你应该使用 BigDecimal 而不是 Long。由于其性质,Oracle 的 NUMBER 对应的类型是 Java 的 BigDecimal。无论如何,您大多使用“数字”作为 ID,您不会将它们用于任何计算。
-
改了顺序,之前的日志表只是换了个顺序。
-
稍后我会尝试 BigDecimal 和 BINARY_DOUBLE。会让你知道结果。'
-
顺便说一句,您在使用 BINARY_DOUBLE 时可能会遇到更多奇怪的问题。该数据库被迁移到 AIX(PowerPC CPU)上的图像。然后您的双精度(Java/Intel)必须转换为不同的表示形式(尽管也符合 IEEE 标准)。 BINARY_DOUBLE 表示运行 DB 服务器的架构的本机浮点表示。
标签: java oracle plsql spring-jdbc ojdbc