spring+jotm+jta+xapool+hibernate+oracle架构中多数据源出现的问题
公司一系统使用了spring+jotm+jta+xapool+hibernate+oracle架构,系统出现了500错误,错误信息如下:
?
?
java.sql.SQLException: SQLException in StandardPoolDataSource:getConnectionexception: java.sql.SQLException: Cannot get connection for URL jdbc:oracle:thin:@10.4.1.110:1521:testdb: 调用中无效的参数at org.enhydra.jdbc.pool.StandardPoolDataSource.getConnection(StandardPoolDataSource.java:218)at org.enhydra.jdbc.pool.StandardPoolDataSource.getConnection(StandardPoolDataSource.java:168)at org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource.getConnection(AbstractRoutingDataSource.java:133)……?
?
?
其中数据源配置的部分bean如下(网上找的示例,和我的格式一样):
?
?
<bean id="dataSource_stat" destroy-method="shutdown"> <property name="dataSource"> <bean id="innerDataSource" destroy-method="shutdown"> <property name="transactionManager"><ref local="jotm"/> </property> <property name="driverName"><value>oracle.jdbc.OracleDriver</value> </property> <property name="url"><value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value> </property> <property name="minCon" value="1"> </bean> </property> <property name="user"><value>t_wms</value> </property> <property name="password"><value>111</value> </property> </bean> <bean id="jotm" name="code">1.部分模块出现该错误,部分模块不会出现。2.出现该错误的模块,有时候会正常,有时候会出现上述错误。3.出现错误的模块中,使用级联操作的页面出现的概率高,查询单独表的页面出现错误的概率小。
?
?
1.排查问题的过程中,首先排除了代码问题,原因是系统部署使用另外获取数据源的方式,如,把数据源配置在resion中,是不会出现该问题的。2.怀疑是jar包冲突的问题。在排查过程中,发现数据库连接的jar包之间没有问题,与数据源配置在resion中系统的lib包中数据连接的jar包是一样的,包括ssh的包。3.怀疑是xa事务控制的问题。
?
? ?在调查xapool的问题时,发现也有coder也出现了类似的问题,不过时间比较早。毕竟xapool 1.5版本是2005年发布的,2006年发布了1.6beat版本后就没再更新过。
?
?
主要解决方案有
?
方案1.
?
? ?如果是使用的1.5版本的
?
Oracle9i有名的内存溢出bug导致:Xapool对PreparedStatement进行了Cache,同时Oracle有一个出名的内存漏洞,PreparedStatement使用之后必须关闭,如果不关闭连续进行SQL查询会造成前面SQL的游标不能释放; Xapool1.5的修改如下:修改StandardConnectionPoolDataSource类的public static final int DEFAULT_PREPAREDSTMTCACHESIZE = 0,(当然也可以用配置的方式来注入)这样就关闭了PreparedStatement的Cache,而且也不会造成什么1.4中关闭连接时的异常等等.
? ? 或者:
下载xapool源码包,然后在org.enhydra.jdbc.pool.GenericPool中,找到life = (Long) unlocked.get(o); 代码之后在下面加入:if (life == null) continue;?
?
? ?建议使用1.6版本的吧,毕竟自己需要查看源代码和修改,如果不慎可能造成不可预知的后果。
?
方案2.可以把数据源修改为
?
<bean id="dataSource_stat" destroy-method="shutdown"> <property name="transactionManager"><ref local="jotm"/> </property> <property name="driverName"><value>oracle.jdbc.OracleDriver</value> </property> <property name="url"><value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value> </property> </property> <property name="user"><value>t_wms</value> </property> <property name="password"><value>111</value> </property> <property name="minCon" value="1"> </bean>?
? ? 这个方案是自己测试发现的,可以使用,但是貌似没有走数据连接池。
?
? 方案3.
? ? ?数据连接池中数据源中都配置用户名和密码,即StandardXAPoolDataSource中要配置user和password,StandardXADataSource中也要配置user和password如:
?
<bean id="dataSourcePool" destroy-method="shutdown"> <property name="dataSource"> <bean id="innerDataSource" destroy-method="shutdown"> <property name="transactionManager"><ref local="jotm"/> </property> <property name="driverName"><value>oracle.jdbc.OracleDriver</value> </property> <property name="url"><value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value> </property> <property name="user"><value>t_wms</value> </property> <property name="password"><value>111</value> </property> <property name="minCon" value="1"> </bean> </property> <property name="user"><value>t_wms</value> </property> <property name="password"><value>111</value> </property> </bean>
?
? 这个问题挺奇怪的,如果有朋友有其他好的解决方案,欢迎交流~~
?
参考地址:http://www.blogjava.net/hunteva/archive/2009/01/20/62936.html
? ? ? ? ? ? ? ?http://forum.springsource.org/archive/index.php/t-28145.html
? ? ? ? ? ? ? ?http://fableking.iteye.com/blog/954153