`
rmzdb
  • 浏览: 78847 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

【原】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在程序里,就可以通过捕获异常,再去获取连接。这里给出我自己的代码:

Java代码 

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”,”jndi/3”);    
		Properties env = new Properties();    
		env.put(Context.INITIAL_CONTEXT_FACTORY,    
		"com.ibm.websphere.naming.WsnInitialContextFactory");    
		Context context = new InitialContext(env);    
		DataSource ds = (DataSource) context.lookup(jndiMap    
		.getProperty(alias));    
		conn = ds.getConnection();    
	}    
	stmt = conn.createStatement();    
	stmt.execute("select 1 from dual");    
} catch (StaleConnectionException sce) {    
	if (retryCount < 3) {    
    		retry = true;    
		retryCount++;    
	} else {    
	retry = false;    
        }    
} catch (Exception e) {    
   	e.printStackTrace();    
} finally {    
	try {    
 	    if (stmt != null) {    
	       stmt.close();    
	    }    
	    if (conn != null && retry) {    
	       conn.close();    
	    }    
	} catch (Exception e) {    
	    e.printStackTrace();    
	}    
    }    
} while (retry);   

注:(1) 不同版本的jndi的提取方式可能不一样。
  (2) 该异常所在websphere的jar包:以当前环境为例,在 plugins/com.ibm.ws.runtime.jar(自己确实找了很久,才引入进来编译的代码)
  当我就要觉得大功告成了,发现又现一个很严重的问题。系统启动没有几分钟,就有异常抛出:数据采集:数据入库异常java.lang.NullPointerException。数据长时间重连后,依旧获取不到连接,就导致了抛异常了,到systemOut.log 上一看,发现问题:

写道

引用
[13-1-29 19:46:39:163 GMT+08:00] 0000002d FreePool E J2CA0045E: 对资源 jndi/sjjh 调用方法 createOrWaitForConnection 时,没有可用的连接。
[13-1-29 19:46:39:165 GMT+08:00] 00000016 FfdcProvider I com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: 已在 /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/ffdc/server1_55a955a9_13.01.29_19.46.39.1622748.txt com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection 299 发出 FFDC 事件。


额外的提示:
First failure data capture(FFDC) 工具是 WebSphere 小组开发的一款可以在第一次异常发生时对其进行详细数据捕获的工具。我们将其移植进入 IBM Systems Director ,并对其功能进行了进一步的封装,从而使其能够针对 Director 这款软件中的各种异常数据进行捕获。FFDC 机制在 Director 启动时随之启动,然后监听异常数据,直至 Director 被关闭。
  
通过查看FFDC事件日志,报出以下日志:

写道

引用
[13-1-29 19:25:41:587 GMT+08:00] FFDC Exception:com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException SourceId:Max connections reached ProbeId:869 Reporter:com.ibm.ejs.j2c.PoolManager@28cc28cc
com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException: Connection not available, Timed out waiting for 180030
at com.ibm.ejs.j2c.FreePool.createOrWaitForConnection(FreePool.java:1562)
at com.ibm.ejs.j2c.PoolManager.reserve(PoolManager.java:2436)
at com.ibm.ejs.j2c.ConnectionManager.allocateMCWrapper(ConnectionManager.java:955)
at com.ibm.ejs.j2c.ConnectionManager.allocateConnection(ConnectionManager.java:609)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:646)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:613)
……(中间省略)……
==> Performing default dump from com.ibm.ejs.j2c.DiagnosticModuleForJ2C :Tue Jan 29 19:25:41 GMT+08:00 2013
Maximum number of connections has been reached, and the connection request has been waiting longer than:ConnectionWaitTime. Two possible solutions : increase the max number of connections, or increase the:ConnectionWaitTime.:
Maximum Connections = :10
Current number of connections = :10
Connection Wait Timout = :180

日志给出了很详细的处理方法,增大最大连接数,或者增大连接等待的时间,因为180秒的等待时间,当连接达到最大的连接数,获取连接时间超过180秒,就会抛出异常了。如果资源允许的话,我们很喜欢调整一下,连接数调整到100,连接等待时间再调整一下。可是情况依然没有好转,100个连接数,启动没有10分钟,就耗尽了。问题没有这么简单。
由于是现场的问题,立马让现场,抓了一个数据库的情况:

写道

引用
Select userName,count(userName) from v&session group by userName

100的连接耗尽,数据库的保有连接是 26 。
  到这,我有点疑惑了,难不成是was连接池的连接池与数据库的连接没有同步。也就是网上有那么几个稀少的提问:was7.0版本的连接池不会自动释放连接,有没有人碰到,我这里的情况貌似是这样,想想这是不是ibm本身的bug问题。开始查找IBM fix List。发现有关J2CA0045E 问题报错, 有两处提到:
  

引用
http://www-01.ibm.com/support/docview.wss?uid=swg21323294

写道

引用
J2CA0045E: Connection not available while invoking method
createOrWaitForConnection for resource jdbc/BPEDB.CWWBB0638E: Failed to connect to the database. The error reported by thedatabase is: com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException:Connection not available, Timed out waiting for 180000.
Cause
This problem likely has two of the following causes:
The connection pool is incorrectly configured
The database settings for the maximum number of connections is incorrect or is lower than the settings of the connection pool in WebSphere Application Server
The embedded Derby database is used for processing the high-workload scenario, or the network deployment Derby server is improperly configured


原因描述的都很简单。连接池配置问题,最小超出最大连接,也属于配置问题,第三个跟我们的项目没有关系。到这里,我们不得不去考虑程序的问题了,我们又做了验证,发现这次
现场问题出来后,数据库的连接就是100了。跟之前的对比,原因:就是之前的抓数据库的信息晚了,导致was自己释放一部分的连接,所以库的保有连接是26。这个时候异常已经抛出来了。看来还应该是程序本身的问题。
后来经过查看代码发现:我们把获取连接写在了循环的里面了,而把关闭连接写在循环的外面。每次在里面通过连接工厂获取连接,当循环的次数为0或较少的时,程序在数据库上的开销几乎没有,即使有部分的连接没有关闭,由was的连接池也关闭了,不至于影响性能,但是当业务量大的时候,获取连接多,而且操作频繁,was关闭掉的连接诊断远远达不到获取连接的速度,就会抛异常了。但是这里比较奇怪的一点,当没有获取连接的时候,在程序的后端,执行close操作,竟然没有报空指针异常,虽然捕获了异常,也没有任何输出,该代码端的结束的log输出也不见了。这让我有点奇怪,这也是我在这个问题上查找原因花了不少时间的一个方面。

总结:was在连接池上的异常,多半都是自己程序上没有及时关闭导致的。在你疯狂的为bug着急的时候,请先看看自己的代码。毕竟第三方的bug是少之又少的。

 

分享到:
评论

相关推荐

    Sosoo 1.0网络爬虫程序.doc

    能会出现超时的情况,通过设置超时时间来限制对某个url连接的最大时间,这样就可以提高处理的速度,但是如果这个值设置太小,可能很多连接都会连接不到,建议使用大于30的值,默认为60s。 robby....

    2009达内SQL学习笔记

    rollback:回溯,回溯到上次操作前的状态,把这次事务操作作废,只有一次(DDL和DCL语句会自动提交,不能回溯)。 可以用commit语句提交,这样就回溯不回了。 set pause on\off :设置分屏(设置不分屏) set pause...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    Sqlite 一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中 W3C 万维网联盟,创建于1994年,是Web技术领域最具权威和影响力的国际中立性技术标准机构。主要的工作是发展 Web 规范,...

    下面是一系列蓝屏中可能出现的代码

    1014 0x000003F6 系统登录数据库中的一个档案必须使用记录或其它备份还原。 已经还原成功。 1015 0x000003F7 系统登录毁损。其中某个档案毁损、或者该档案的 系统映对内存内容毁损、会是档案无法复原。 1016 0x...

    windows蓝屏错误代码

    1014 0×000003F6 系统登录数据库中的一个档案必须使用记录或其它备份还原。 已经还原成功。 1015 0×000003F7 系统登录毁损。其中某个档案毁损、或者该档案的 系统映对内存内容毁损、会是档案无法复原。 1016 0×...

    IMUCourseNet:内蒙古大学课程现场演示

    IMUCourseNet Course site demo for Inner Mongolia University....虽然你们没有使用Git,但是我每次合并你们的代码都在使用Git,所以有了70多次的commit记录。 数据库名称:imucoursenet 连接账号:root 连接密码:123456

    arcgis工具

    (补充其他工具:Union,把多个图斑联合起来并形成一个新的连接在一起的图斑,原图斑无变化,联合后的图斑不继承原任何图斑的属性;Merge,把多个图斑合并到其中一个图斑上并继承它的属性,原图斑变化;Split用于间断...

    springmybatis

    1.Configuration.xml 是 mybatis 用来建立 sessionFactory 用的,里面主要包含了数据库连接相关东西,还有 java 类所对应的别名,比如 &lt;typeAlias alias="User" type="com.yihaomen.mybatis.model.User"/&gt; 这个别名...

    测试培训教材

    但是还需要修改以前Project的数据库连接属性 否则会提示错误 然后还要修改 C:\Program Files\Mercury\Quality Center\repository\qc中的dbcon.txt: qcsiteadmin_db@192.168.1.12.1433. 还有 C:\Program Files\...

Global site tag (gtag.js) - Google Analytics