was的一次数据库连接不了的处理记录
环境:WAS 7.0.0.0
Jdk :自带1.6
Linux环境:Linux, version 2.6.18-194.1.AXS3
Database 产品版本:Oracle Database 11g Release 11.1.0.0.0 - Production
数据源配置驱动:11.1.0.1.0 (后来更换 11.2.0.1.0 版本)
遇到的几个棘手问题:
1.Error while registering Oracle JDBC Diagnosability MBean.
javax.management.MalformedObjectNameException: Invalid character '
' in value part of property
at javax.management.ObjectName.construct(ObjectName.java:613)
at javax.management.ObjectName.<init>(ObjectName.java:1405)
at oracle.jdbc.driver.OracleDriver.registerMBeans(OracleDriver.java:303)
at oracle.jdbc.driver.OracleDriver$1.run(OracleDriver.java:213)
at java.security.AccessController.doPrivileged(AccessController.java:202)
at oracle.jdbc.driver.OracleDriver.<clinit>(OracleDriver.java:209)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
at java.lang.Class.forNameImpl(Native Method)
at java.lang.Class.forName(Class.java:136)
at org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1415)
at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:114)
at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2833)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2829)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1840)
at
解决:
发现还是jdbc驱动问题,原因因该是与bug有关,因此从新从otn.oracle.com下载驱动升级解决问题。
ojdbc6.jar的驱动版本可以运行java -jar ojdbc6.jar查看,如果是Oracle 11.1.0.6.0-Production+ JDBC 4.0 compiled with JDK6,带+号就是补丁版本,否则是没有打补丁的,仍然可能出错。
或者直接下载 Oracle 11.1.0.7.0-Production JDBC 4.0 compiled with JDK6 这个包的ojdbc6.jar
下载地址http://www.oracle.com/technology/tech/java/sqlj_jdbc/index.html
WAS数据源配置:
我的项目中,涉及到多个库的连接,并且在程序中,对多个库有操作。其中每个库本身又保持自己业务库的连接。项目中自己的库,一方面通过注入,由hibernate去管理。作为自己的本身业务库,另一方面又注入到一个连接工厂,维持一个所有数据源的Map。供程序调用。而所有的连接是用was的连接池管理。
刚开始数据总是会报一个com.ibm.websphere.ce.cm.StaleConnectionException的异常。
原因分析:WebSphere并不保证缓存的连接都是有效的,在这种情况下当用户从连接池中取得了一个失效的连接并且用来进行数据库操作时,WebSphere就会抛出StaleConnectionException。在StaleConnectionException出现之前,用户无法判断这是否为一个无效连接。详见:http://www.ibm.com/developerworks/cn/websphere/library/techarticles/0601_chenzhh/index.html
文章中说到,是由于websphere与数据库之间的连接中断导致。这可以验证我之前遇到的情况。日志里面有数据库的IO异常错误。网络不稳定可能是一个因素。但是后来,我调整了环境后,仍然有错。这里的连接池的缓存可能还跟连接池的配置项有关。因为我自己的程序对数据库的操作数据比较多,在程序开始前,先从一个库到查询大量的数据,再到另一个库里去插入大量的数据。而我获取连接在一开始就获取了,由于长时间的连接闲置,was连接池可能会把物理连接给断掉。这可能也是导致无效连接的一个因素。后来我把获取连接的位置调整了一下,问题有了好转。上述链接,说到避免无效连接,其实就是在连接之前加个测试语句。这在proxool等连接池组件都有配置实现,但是我们用jndi在程序里,就可以通过捕获异常,再去获取连接。这里给出我自己的代码:
do {
Statement stmt = null;
try {
if (retryCount == 0) {
conn = getDataSource(alias).getConnection();
} else {
Properties jndiMap = new Properties();
jndiMap.put(“1”,”jndi/1”);
jndiMap.put(“2”,”jndi/2”);
jndiMap.put(“3”,”j