航海日志(2) ----from Oracle to DB2

本文介绍了一种从Oracle迁移到DB2数据库时遇到的锁表问题及其解决方法,并详细解析了在Websphere环境下出现resultsetclosed错误的原因及解决步骤。

航海日志(2) ----from Oracle to DB2

---DB2锁表及 ResultSet Closed

 

                                李俊杰

概述

我们原有的系统是架构在Oracle数据库服务器之上的,现在要迁移到DB2数据库服务器上,Websphere作为应用服务器。在原有的系统中后来集成了工作流系统,该工作流系统的持久层是使用Hibernate,这就造成工作流使用工作流系统的数据库连接,而业务系统使用Type4的数据库连接。在迁移过程中发现锁表现象,修改Hibernate的配置文件后,在本地的jboss服务器上没问题(程序员在本地使用的是jboss服务器),但在websphere服务器上调用工作流时出现“result set closed”的错误。下面我将详细介绍其原因及解决方案。

DB2数据库锁表

锁表问题现象及原因分析

数据库操作几次即出现锁表现象,无法继续操作,分析log得出锁表信息“LOCK_ESCALATION”和“LOCK TIMEOUT”等字眼,就可以肯定是锁表了。我们又分析了我们的系统,发现业务系统使用的是Type4数据源连接数据库,而hibernate.cfg.xml文件中定义的是JDBC连接,所以出现了锁表现象。

<property name="connection.driver_class">com.ibm.db2.jcc.DB2Driver</property>
  <property name="connection.url">jdbc:db2://10.10.19.169:50000/sinochem</property>
  <property name="connection.username">db2admin</property>
  <property name="connection.password">db2admin</property>

而业务系统使用的数据库连接的定义是在oracle-ds.xml这样的:

<?xml version="1.0" encoding="UTF-8"?>

<datasources>

  <local-tx-datasource>

    <jndi-name> jdbc/cpf/type4</jndi-name>

    <connection-url>jdbc:db2://10.10.19.169:50000/sinochem</connection-url>

    <driver-class>com.ibm.db2.jcc.DB2Driver</driver-class>

    <user-name>db2admin</user-name>

    <password>db2admin</password>

    <min-pool-size>3</min-pool-size>

    <max-pool-size>6</max-pool-size>

    <idle-timeout-minutes>5</idle-timeout-minutes>

  </local-tx-datasource>

</datasources>

应用服务器在启动的过程中,通过servlet把该文件的内容读入内存,并使用了JDBC的连接。

锁表解决方法

<property name="connection.datasource">java:comp/env/jdbc/cpf/type4</property>

其中“jdbc/cpf/type4为数据源名称,这样业务系统和工作流系统采用统一的数据源,则解决了锁表问题。这样的解决方法jboss上面是没有问题的,因为jboss上使用的是本地的配置文件oracle-ds.xml创建的数据源。

Websphere问题(result set closed)原因分析

当我们的系统部署到Websphere上,并配置JNDI为“jdbc/cpf/type4的数据源,在调用工作流(工作流后台是Hibernate)时出现“com.ibm.db2.jcc.b.SqlException: Invalid operation: result set closed

”,根据网上的资料说是ResultSet嵌套调用,但我们分析代码,并没有出现ResultSet嵌套调用的可能性,又采用了其他方式证明了Hibernate是调用的Websphere配置的数据源。最后发现是DB2JDBC驱动存在bug,原因是多线程运行的线程安全问题,StatementResultSet共享线程引起的问题,正常情况下如果使用Statement执行完一个查询,又去执行另一个查询时这时候第一个查询的结果集就会被关闭,也就是说,所有的Statement的查询对应的结果集是一个,如果调用Connectioncommit()方法也会关闭结果集。可保持性就是指当ResultSet的结果被提交时,是被关闭还是不被关闭。JDBC2.01.0提供的都是提交后ResultSet就会被关闭。 

resultSetHoldability表示在结果集提交后结果集是否打开,取值有两个:
ResultSet.HOLD_CURSORS_OVER_COMMIT:
表示修改提交时,不关闭数据库。
ResultSet.CLOSE_CURSORS_AT_COMMIT
:表示修改提交时ResultSet关闭。

websphere的数据源连接池的配置过程中缺省是第2中方式,这就是造成错误的原因。

 

修改步骤如下所示:

  根据上面的错误原因分析,是websphere的数据源连接池的resultSetHoldability配置参数需要修改,则在websphere控制台上资源->JDBC提供者,如下:

 

 

点击DB2 Universal JDBC Driver Provider->数据源 ,如下图所示:

选择你要修改参数的数据源,如下图所示“jdbc/cpf/type4

数据源详细配置页面,上面有具体的数据源配置,点击右侧的“定制属性”,如下图所示

 

在下面的数据源的定制属性中选择“resultSetHoldability”参数,如下图所示:

 

如下图所示,修改“resultSetHoldability”属性的值,缺省是2,修改为1

 

修改属性后保存,并重启Websphere应用服务器,则大功告成!

努力,在于我热爱我的事业,与中国的软件一起走向成熟,走向世界。
   
联系作者:lijj_72@hotmail.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值