Weblogic10.3.5 数据库连接被异常回收问题解析

标签: weblogic10 数据库 异常 | 发表时间:2013-10-10 16:18 | 作者:走走停停又三年
出处:http://www.blogjava.net/
      首先介绍一个JDBC参数InactiveConnectionTImeout,该参数用于强制回收那些被泄露的连接(长时间不使用的连接、未被程序正确释放的连接),避免连接池因为泄露导致无连接可用。当然该参数只是起辅助作用,解决问题知道还是在于完善应用程序。

      本文和该参数有关,早期的8.1\9.2中,设定该参数时,定时器(内部的连接池维护Task)只会清理那些长期未被使用的空闲连接(从名字上可以看出来),即对于运行一个长时间执行SQL的连接而言,它是不受影响的。但不知道从10.3哪个版本开始(我测试的是10.3.5),该参数对于长时间执行SQL的连接也进行强制回收了(这个比较不合理,虽然对于正在执行的Tx影响不大)。Debug了一下,发现SQL执行时间大于4*InactiveConnectionTimeout时,这个SQL执行完成时,会出现 <BEA-001153> <Forcibly releasing inactive connection " weblogic.jdbc.wrapper.PoolConnection_oracle_jdbc_driver_T4CConnection@1" back into the connection pool "TestDS", currently reserved by: java.lang.Exception这样的错误。

//该线程为内部Task执行线程,该线程目前处于被阻塞状态,等待SQL执行结束后回收连接
"[STUCK] ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=2 tid=0x2c4d3400 nid=0x1a14 waiting for monitor entry [0x
319bf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at oracle.jdbc.driver.PhysicalConnection.rollback(PhysicalConnection.java:3896)
        - waiting to lock <0x0e6191d8> (a oracle.jdbc.driver.T4CConnection)
        at weblogic.jdbc.wrapper.Connection.forcedCleanup(Connection.java:156)
        at weblogic.common.resourcepool.ResourcePoolImpl.timeoutInactiveResources(ResourcePoolImpl.java:1955)
        at weblogic.common.resourcepool.ResourcePoolImpl.access$8(ResourcePoolImpl.java:1916)
        at weblogic.common.resourcepool.ResourcePoolImpl$ResourcePoolMaintanenceTask.timerExpired(ResourcePoolImpl.java:2680)
        at weblogic.timers.internal.TimerImpl.run(TimerImpl.java:273)
        at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

//该线程为应用执行线程,目前该线程SQL正在运行,他阻塞(阻塞对象为T4CConnection)了内部Task执行线程
"[STUCK] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=2 tid=0x2c7b4c00 nid=0x1100 runnable [0x2cf7e000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        ......
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1315)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576)
        at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3677)
        - locked <0x0e6191d8> (a oracle.jdbc.driver.T4CConnection)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1374)
        at weblogic.jdbc.wrapper.PreparedStatement.execute(PreparedStatement.java:102)
        at com.bea.cs.test.jdbc.DriverTest.inactiveTimeoutTest(DriverTest.java:537)
        at jsp_servlet.__ds._jspService(__ds.java:86)

        从上面的线程堆栈可以看到,内部Task线程正在调用connection的rollback,即回滚连接上的本地事务。如果应用线程上使用的连接设为auto commit的话,该SQL执行不会被rollback,否则该SQL虽然执行完成也会被rollback调(全局事务中,某个事务分支使用的连接一定是非auto commit的),所以该问题对涉及全局事务的应用影响比较大。

        下面我们在看看连接被回收的时间点为什么会出现在3-4个InactiveConnectionTimeout之间。当内部Task执行,发现到了InactiveConnectionTimeout时间点后,它会调用timeoutInactiveResources()方法开始进行连接清理。那么为什么正在执行SQL的连接会被标志为非活动连接呢?这里涉及连接状态的三个标志位,分别为:conn_in_use,connUsed,hang_state,这三个标志位是其中的关键(getUsed()和setUsed()方法中会进行标志位操作及读取,如果对于某个连接getUsed()返回false的话,该连接会被清理)。下面我们看看其中标志位的变化过程: SQL开始执行时,preInvokeHandler会被这三个标志位进行设定。

初始值如下:
conn_in_use-->true
hang_state-->conn_state_in_use
connUsed-->true

第一次InactiveConnectionTimeout检查,getUsed返回true,同时调用setUsed(false),标志位变化如下:
conn_in_use-->true
hang_state-->conn_state_idle_suspect
connUsed-->true

第二次InactiveConnectionTimeout检查,getUsed返回true,同时调用setUsed(false),标志位变化如下:
conn_in_use-->false
hang_state-->conn_state_hang_suspect
connUsed-->false

第三次InactiveConnectionTimeout检查,getUsed返回true,
hang_state-->conn_state_in_use(从conn_state_hang_suspect变成conn_state_in_use)
同时调用setUsed(false),标志位变化如下:
conn_in_use-->false
connUsed-->false
hang_state-->conn_state_idle_suspect(从conn_state_in_use变成conn_state_idle_suspect)

第四次InactiveConnectionTimeout检查,getUsed返回false,开始回收该连接。

从上面的变化时间点可以看到从第一次到第四次检查经历了完整的3个InactiveConnectionTimout周期,而从SQL执行到第一次检查点,这个时间小于一个InactiveConnectionTimeout,所以连接开始被回收的时间点介于3-4个InactiveConnectionTimeout之间。






相关 [weblogic10 数据库 异常] 推荐:

数据库异常hang住解决

- - BlogJava-qileilove
测试库同事反应查询更新数据很慢,有时甚至表都打不开,后来通过服务器【linux】的top命令查看了下,cpu和mem占用正常,但wait高达80%多(下面两图显示的就是问题前后观察EM对比的截图,版本是oracle10gR2,EM的效果比oracle11gR2逊色不少哈):. --oracle级别kill session.

Weblogic10.3.5 数据库连接被异常回收问题解析

- - BlogJava-首页技术区
      首先介绍一个JDBC参数InactiveConnectionTImeout,该参数用于强制回收那些被泄露的连接(长时间不使用的连接、未被程序正确释放的连接),避免连接池因为泄露导致无连接可用. 当然该参数只是起辅助作用,解决问题知道还是在于完善应用程序.       本文和该参数有关,早期的8.1\9.2中,设定该参数时,定时器(内部的连接池维护Task)只会清理那些长期未被使用的空闲连接(从名字上可以看出来),即对于运行一个长时间执行SQL的连接而言,它是不受影响的.

oracle数据库异常关闭之后恢复

- - Oracle - 数据库 - ITeye博客
oracle服务器重启之后无法启动,startup时报. ORA-03113: 通信通道的文件结尾 shutdown 时报:ORA-27101: shared memory realm does not exist. 解决办法参见博文: http://soulful.blog.51cto.com/468033/389570/.

数据库sharding

- - 数据库 - ITeye博客
当团队决定自行实现sharding的时候,DAO层可能是嵌入sharding逻辑的首选位置,因为在这个层面上,每一个DAO的方法都明确地知道需要访问的数据表以及查询参数,借助这些信息可以直接定位到目标shard上,而不必像框架那样需要对SQL进行解析然后再依据配置的规则进行路由. 另一个优势是不会受ORM框架的制约.

数据库索引

- - CSDN博客推荐文章
索引是由用户创建的、能够被修改和删除的、实际存储于数据库中的物理存在;创建索引的目的是使用户能够从整体内容直接查找到某个特定部分的内容. 一般来说,索引能够提高查询,但是会增加额外的空间消耗,并且降低删除、插入和修改速度. 1.聚集索引:表数据按照索引的顺序来存储的. 2.非聚集索引:表数据存储顺序与索引顺序无关.

数据库事务

- - 数据库 - ITeye博客
事务传播发生在类似以下情形:. 假设methodB的配置是:. 如果methodA在事务里,那么methodB也在这个事务中运行. 如果methodA不在事务里,那么methodB重新建立一个事务运行. 如果methodA在事务里,那么methodB也在这个事务中运行. 如果methodA不在是事务里,那么methodB在非事务中运行.

数据库优化

- - 数据库 - ITeye博客
程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点: . a) SQL的使用规范: .   i.尽量避免大事务操作,慎用holdlock子句,提高系统并发能力.   ii.尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接.   iii.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作.

数据库调优

- - 数据库 - ITeye博客
1、1、调整数据结构的设计. 这一部分在开发信息系统之前完成,程序员需要考虑是否使用ORACLE数据库的分区功能,对于经常访问的数据库表是否需要建立索引等. 这一部分也是在开发信息系统之前完成,程序员在这一步需要考虑应用程序使用什么样的体系结构,是使用传统的Client/Server两层体系结构,还是使用Browser/Web/Database的三层体系结构.

MySQL数据库的修复

- Xin - 博客园-首页原创精华区
找到mysql的安装目录的bin/myisamchk工具,在命令行中输入:. 然后myisamchk 工具会帮助你恢复数据表的索引. 好象也不用重新启动mysql,问题就解决了. 当你试图修复一个被破坏的表的问题时,有三种修复类型. 如果你得到一个错误信息指出一个临时文件不能建立,删除信息所指出的文件并再试一次--这通常是上一次修复操作遗留下来的.