WSO2 Data Services调用Oracle存储过程引发连接池泄漏如何解决?
Oracle存储过程调用引发WSO2连接池泄漏的解决方案
问题背景
使用Oracle数据库,在WSO2中定义查询调用存储过程LOG3NRPARTYRES,通过Template Mediator调用对应操作后,存储过程执行成功,但Toad检查发现连接始终处于打开状态,引发连接池泄漏。已配置连接池的removeAbandoned相关属性,但问题未解决。
相关配置代码
存储过程查询定义:
<query id="logThirdPartyResponseProc" useConfig="DBConfig"> <sql>CALL LOG3NRPARTYRES(:P_APINAME, :P_SVCSOURCE, :P_APPREQID, :P_GLOBALID, :P_BODY, :P_ERR_CODE)</sql> <param type="IN" name="P_APINAME" paramType="SCALAR" sqlType="STRING" optional="true" defaultValue="#{NULL}" /> <param type="IN" name="P_SVCSOURCE" paramType="SCALAR" sqlType="STRING" optional="true" defaultValue="#{NULL}" /> <param type="IN" name="P_APPREQID" paramType="SCALAR" sqlType="STRING" optional="true" defaultValue="#{NULL}" /> <param type="IN" name="P_GLOBALID" paramType="SCALAR" sqlType="STRING" optional="true" defaultValue="#{NULL}" /> <param type="IN" name="P_BODY" paramType="SCALAR" sqlType="CLOB" optional="true" defaultValue="#{NULL}" /> <param type="OUT" name="P_ERR_CODE" paramType="SCALAR" sqlType="STRING" optional="false" /> <result element="result" rowName="results"> <element name="errorCode" column="P_ERR_CODE" xsdType="string" requiredRoles="" /> </result> </query>
Template Mediator调用代码:
<template name="TPLogThirdPartyRequest" xmlns="http://ws.apache.org/ns/synapse"> <parameter defaultValue="" isMandatory="false" name="apiName"/> <parameter defaultValue="" isMandatory="false" name="svcSource"/> <sequence> <dataServiceCall serviceName="DBTest"> <operations type="single"> <operation name="logThirdPartyRequestOpration"> <param evaluator="xml" expression="$func:apiName" name="pApiName"/> <param evaluator="xml" expression="$func:svcSource" name="pSvcSource"/> <param evaluator="xml" expression="get-property('pAppReqId')" name="pAppReqId"/> <param evaluator="xml" expression="get-property('pGlobalId')" name="pGlobalId"/> <param evaluator="xml" expression="get-property('pThirPartyRequestBody')" name="pBody"/> </operation> </operations> <source type="inline"/> <target name="logThirdPartyRequestErrorCode" type="property"/> </dataServiceCall> <log level="full"/> </sequence> </template>
已配置的连接池属性:
pool_options.removeAbandoned = true pool_options.removeAbandonedTimeout = 60 # wait in seconds pool_options.logAbandoned = true
解决方案
1. 确保OUT参数被完整读取
WSO2 Data Service如果未完成OUT参数的读取,可能不会释放连接。在dataServiceCall后显式访问目标属性,触发参数读取:
<dataServiceCall serviceName="DBTest"> <!-- 原有配置 --> </dataServiceCall> <!-- 新增:显式打印OUT参数,确保WSO2完成读取 --> <log level="custom"> <property name="ThirdPartyErrorCode" expression="get-property('logThirdPartyRequestErrorCode')"/> </log>
2. 添加Oracle专属连接池属性
修改WSO2数据源配置文件(如repository/conf/datasources/master-datasources.xml),针对Oracle添加以下关键属性:
<datasource> <name>DBConfig</name> <description>Oracle DB Connection</description> <jndiConfig> <name>jdbc/DBConfig</name> </jndiConfig> <definition type="RDBMS"> <configuration> <url>jdbc:oracle:thin:@//your-db-host:1521/your-service</url> <username>your-username</username> <password>your-password</password> <driverClassName>oracle.jdbc.OracleDriver</driverClassName> <maxActive>50</maxActive> <maxIdle>10</maxIdle> <minIdle>5</minIdle> <defaultAutoCommit>false</defaultAutoCommit> <removeAbandoned>true</removeAbandoned> <removeAbandonedTimeout>60</removeAbandonedTimeout> <logAbandoned>true</logAbandoned> <!-- Oracle专属属性 --> <connectionProperties> <property name="oracle.jdbc.freeConnectionOnCommit" value="true"/> <property name="oracle.jdbc.autoCloseUnusedStatement" value="true"/> <property name="oracle.jdbc.ReadTimeout" value="30000"/> </connectionProperties> </configuration> </definition> </datasource>
注意:
defaultAutoCommit=false需要确保存储过程自身处理事务,或在Data Service中配置事务。
3. 配置Data Service事务边界
在查询定义中添加事务属性,确保事务完成后连接释放:
<query id="logThirdPartyResponseProc" useConfig="DBConfig" transactional="true"> <!-- 原有查询配置 --> </query>
或者在dataServiceCall中指定事务类型:
<dataServiceCall serviceName="DBTest" transactionType="LOCAL"> <!-- 原有操作配置 --> </dataServiceCall>
4. 验证连接池配置位置与生效
确认removeAbandoned等属性是配置在对应数据源的配置节点中,而非其他文件。修改后重启WSO2服务器,确保配置生效。
5. 显式关闭结果集
在查询定义中添加closeResultset="true",强制关闭结果集释放连接:
<query id="logThirdPartyResponseProc" useConfig="DBConfig" closeResultset="true"> <!-- 原有查询配置 --> </query>
6. 升级软件版本
如果使用的WSO2版本较旧(如EI 6.x早期版本),存在已知的Data Service连接泄漏bug,升级到最新稳定版本;同时确保Oracle JDBC驱动版本与数据库匹配(推荐ojdbc8/ojdbc11)。
内容的提问来源于stack exchange,提问作者Wu Huang
相关产品推荐
相关产品推荐

