ITPub博客

【ojdbc14.jar】由于Oracle驱动ojdbc14.jar导致千万富翁破产之始末

原创 Linux操作系统 作者:secooler 时间:2012-03-09 22:56:45 2 删除 编辑
  这是一个“千万富翁”瞬间变为“贫民”的真实过程。且听我慢慢道来。

1.故障模拟过程
  1)先看一段JAVA代码对字符串读取转换后的数值表示形式的差异
  这段代码实现的功能是从平文本文件中将字符串表示形式的内容转化为数值并打印出结果。
Normal 0 false false false EN-US ZH-CN X-NONEpackage org.seco.sclcore.test;   import java.math.BigDecimal;   public class Sample {     /**    * @param args    */   public static void main(String[] args)   {     // TODO Auto-generated method stub         System.out.println(getSalesMoney("26947280"));     System.out.println(getSalesMoney("122936367"));   }     public static BigDecimal getSalesMoney(String value)   {     String stringValue;     boolean isNegative = false;     if (value.indexOf("-") != -1)     {       stringValue = value.replace("-", "");       isNegative = true;     }     else     {       stringValue = value;     }     BigDecimal result = BigDecimal.ZERO;     if (isNegative)     {       double doubleValue = -1;       result =           BigDecimal.valueOf(Double.valueOf(stringValue).doubleValue()).multiply(               BigDecimal.valueOf(doubleValue));     }     else     {       result = BigDecimal.valueOf(Double.valueOf(stringValue).doubleValue());     }     return result;   }   }
2)代码输出结果
  代码中显式的将"26947280"和"122936367"字符串读取并转化为数字。结果对应如下:
"26947280"  -- 2.694728E+7
"122936367" -- 122936367

  规律:字符串中以数字零结尾的内容转化为数字后以2.694728E+7这种科学计数法的形式保存,而非零几位的内容还是以原有形式显式。

  重点关注科学计数法表示的结果,此处"26947280"结尾处的零已被去掉。2.694728E+7这种科学计数法表示的数字就是数字26947280,此处没有问题。

  3)入库后故障出现
  JAVA代码将结果保存到Oracle数据库后,诡异的事情发生了。原先以科学计数法显示的2.694728E+7数值被存入Oracle数据库后变成了26.9472,如下所示。

错误值    实际值
26.9472    26947280

  这种错误是绝对无法容忍的。
  原本将近两千七百万人民币的资产幻灭了,变成了不到二十七元人民币。这是何等的荒谬,谁都是无法承受这种从千万富翁变为贫民的打击。

2.故障分析过程
  看到这个荒谬的错误后我们需要做的是冷静、冷静……还是冷静。
  仔细的去分析导致这个错误的最终原因到底在哪里。
  1)第一种推测:JAVA本身的问题
  这种可能性基本可以排除。因为在我们的测试代码中返回的数值上看,即便数字表示形式不一样(科学计数法与否),但是最终转化为数值是忠于原字符串本身内容的。也就是说
2.694728E+7就是表示26947280,122936367还是其自身。

  2)第二种推测:Oracle数据库本身的问题
这种可能性也站不住脚,试想一下,作为一款大牌商业数据库软件的Oracle怎么会随随便便将客户的数据篡改呢。
Oracle会将应用程序传过来的内容原原本本的存放到数据库中,用于后续的展示或处理。

  3)第三种推测:问题出在应用程序和Oracle数据库之间
  JAVA应用程序是通过ojdbc14.jar这个驱动程序与Oracle数据库进行衔接的。莫非问题出在这个环节?
  (1)查看当前ojdbc14.jar文件的版本
  版本查看方法:可以使用解压软件打开ojdbc14.jar文件,查看META-INF文件夹中的MANIFEST.MF文件,内容如下:
Manifest-Version: 1.0
Specification-Title:    Oracle JDBC driver classes for use with JDK14
Sealed: true
Created-By: 1.4.2_08 (Sun Microsystems Inc.)
Implementation-Title:   ojdbc14.jar
Specification-Vendor:   Oracle Corporation
Specification-Version:  Oracle JDBC Driver version - "10.2.0.1.0"
Implementation-Version: Oracle JDBC Driver version - "10.2.0.1.0"
Implementation-Vendor:  Oracle Corporation
Implementation-Time:    Wed Jun 22 11:19:45 2005

Name: oracle/sql/converter/
Sealed: false

Name: oracle/sql/
Sealed: false

Name: oracle/sql/converter_xcharset/
Sealed: false

  可见,这里使用的是10.2.0.1.0这个10g版本中的最基础的驱动程序。

  (2)尝试下载10g最新的驱动程序重新测试
10g的最新ojdbc14.jar文件的版本信息如下:
Manifest-Version: 1.0
Specification-Title:    Oracle JDBC driver classes for use with JDK14
Sealed: true
Created-By: 1.4.2_14 (Sun Microsystems Inc.)
Implementation-Title:   ojdbc14.jar
Specification-Vendor:   Oracle Corporation
Specification-Version:  Oracle JDBC Driver version - "10.2.0.5.0"
Implementation-Version: Oracle JDBC Driver version - "10.2.0.5.0"
Implementation-Vendor:  Oracle Corporation
Implementation-Time:    Thu Apr  8 03:40:31 2010

Name: oracle/sql/converter/
Sealed: false

Name: oracle/sql/
Sealed: false

Name: oracle/sql/converter_xcharset/
Sealed: false

  10g最新版本的驱动是10.2.0.5.0。
  在更换了驱动程序之后,之前的故障迎刃而解。原来罪魁祸首就是APP与DB之间的驱动程序
ojdbc14.jar

3.故障处理方法
  通过上面的分析过程已经确认是Oracle驱动程序ojdbc14.jar版本过低导致的,因此故障处理方法很直接,替换生产环境中10.2.0.1版本的驱动为10.2.0.5驱动。

4.小结
  本文中提到的故障场景影响是很恶劣的。即便在替换驱动后依然有很多善后工作要做,比如将已经入库的错误数据的查找并调整正确。
  在JAVA应用程序和数据库之间的驱动选取方面需要注意,基本要求,保证驱动版本和数据库的版本保持一致,或者使用较新版本的驱动程序。
  这个故障带给我们的启示是:任何一个环节都有可能存在重大的隐患,细致严谨永远是IT人最重要的职业素质。

Good luck.

secooler
12.03.09

-- The End --


请登录后发表评论 登录
全部评论
Oracle ACE 总监,OCM联盟(ocmu.org)创始人,恩墨学院(enmoedu.com)创始人,ITPUB Oracle专题深入讨论版版主,资深Oracle数据库专家,北京大学理学硕士,获Oracle OCM 10g 11g认证,ACOUG核心成员,DATAGURU专家团成员,Blogger。Good luck.

注册时间:2008-03-16

  • 博文量
    797
  • 访问量
    7853066