如何使用springs在tomcat连接池中实现XA连接支持?

Posted

技术标签:

【中文标题】如何使用springs在tomcat连接池中实现XA连接支持?【英文标题】:How to implement XA connection support in tomcat connection pool using springs? 【发布时间】:2015-12-17 11:08:28 【问题描述】:

我必须在我的 mule 流中实现支持 XA 事务的 jdbc 连接池。使用弹簧,我实现了如下数据源

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

<mule xmlns:core="http://www.mulesoft.org/schema/mule/core"
    xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
    xmlns:jbossts="http://www.mulesoft.org/schema/mule/jbossts" xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
    xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking"
    xmlns:jdbc-ee="http://www.mulesoft.org/schema/mule/ee/jdbc" xmlns="http://www.mulesoft.org/schema/mule/core"
    xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.4.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/ee/jdbc http://www.mulesoft.org/schema/mule/ee/jdbc/current/mule-jdbc-ee.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/jbossts http://www.mulesoft.org/schema/mule/jbossts/current/mule-jbossts.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">

    <spring:beans>
        <spring:bean id="mysql_Pooled_Data_Source" class="org.apache.tomcat.jdbc.pool.XADataSource"
            name="Bean">
            <spring:property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <spring:property name="url"
                value="jdbc:mysql://10.213.32.13:3306/DB_NE60BMRS_REP" />
            <spring:property name="username" value="Tester249" />
            <spring:property name="password" value="Tester249" />
            <spring:property name="maxActive" value="100" />
            <spring:property name="minIdle" value="10" />
            <spring:property name="initialSize" value="5" />
        </spring:bean>
    </spring:beans>

    <jdbc-ee:connector name="Reporting_Database"
        dataSource-ref="MySQL_Pooled_Data_Source" validateConnections="true"
        queryTimeout="-1" pollingFrequency="0" doc:name="Database">
        <reconnect blocking="false" frequency="10000" count="3"></reconnect>
    </jdbc-ee:connector>
    <vm:connector name="VM_Connector" validateConnections="true"
        doc:name="VM_Connector" createMultipleTransactedReceivers="true"
        numberOfConcurrentTransactedReceivers="4">
    </vm:connector>

    <flow name="ApiKeyLoadImplFlow" doc:name="ApiKeyLoadImplFlow"
        initialState="started">

        <vm:inbound-endpoint exchange-pattern="request-response"
            doc:name="Impl_ApiKeyLoad_Req" path="ImplApiKeyLoadReq"
            connector-ref="VM_Connector" responseTimeout="$vm.response.timeout">
            <xa-transaction action="BEGIN_OR_JOIN" />
        </vm:inbound-endpoint>
        <logger message="Start of Api Key Load Implementation" level="DEBUG"
            doc:name="ENTRY_LOG" />
        <set-variable variableName="FlowData" value="#[payload]"
            doc:name="FlowData" />
        <set-variable variableName="#['UserId']" value="#[payload.getUserID()]"
            doc:name="UserID" />

            <jdbc-ee:outbound-endpoint exchange-pattern="request-response"
            queryKey="checkdata" queryTimeout="-1" connector-ref="Reporting_Database"
            doc:name="Check_Value_Exists">
            <xa-transaction action="JOIN_IF_POSSIBLE" />
            <jdbc-ee:query key="checkdata"
                value="$ftp.db.t_bmrs_api_keys.checkdata.query" />

        </jdbc-ee:outbound-endpoint>

        <logger message="End of Api Key Load Implementation" level="DEBUG"
            doc:name="EXIT_LOG" />


        <catch-exception-strategy doc:name="Catch Exception Strategy">
            <logger level="WARN" doc:name="Exception_Log"
                message="Exception in ApiKeyLoadImplFlow #[System.getProperty('line.separator')] Error Description = #[exception.getMessage()]" />

        </catch-exception-strategy>
    </flow>
</mule>

但我面临以下例外情况。如何使用springs实现XAconnection对上述池化的支持?

ERROR 2015-12-17 15:51:37,626 [[apikey_load_phase3].Mule.02] org.mule.retry.notifiers.ConnectNotifier: Failed to connect/reconnect: EEJdbcConnector

  name=Reporting_Database
  lifecycle=initialise
  this=15db0f5
  numberOfConcurrentTransactedReceivers=4
  createMultipleTransactedReceivers=false
  connected=false
  supportedProtocols=[jdbc]
  serviceOverrides=<none>

 *Root Exception was: Connection from pool does not implement javax.sql.XAConnection(SQL Code: 0, SQL State: + null). Type: class java.sql.SQLException*

【问题讨论】:

我认为你需要 TomEE。我的理解是 XA 事务是跨数据库(或其他)的。因此,如果我有 Sybase 和 Oracle,并且我想在一个事务中对两者进行一些活动。我的理解也是,这是您在完整的 JEE 应用服务器上执行的操作,而不仅仅是容器。 【参考方案1】:

你需要更换:

com.mysql.jdbc.Driver

与:

com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

【讨论】:

我已经实现如下替换 com.mysql.jdbc.Driver 与 com.mysql.jdbc.jdbc2.optional.MysqlXADataSource 但我现在面临以下问题 异常堆栈为:1. 逻辑句柄不再有效(SQL 代码:0,SQL 状态:+ null) (java.sql.SQLException) com.mysql.jdbc.SQLError:927 (null) 2. 逻辑句柄不再有效(java.sql.SQLException) (org.mule.api.transaction.TransactionException) org.mule.transport.jdbc.xa.ConnectionWrapper:299 (mulesoft.org/docs/site/current3/apidocs/org/mule/api/…) 注意那里发生了什么。由于您使用的是 JDBC 驱动程序的企业版,因此​​请使用 MuleSoft 开票。

以上是关于如何使用springs在tomcat连接池中实现XA连接支持?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring/Tomcat 中完全禁用 JDBC 连接池?

spring配置连接池和dao使用jdbcTemplate

为啥要用Spring管理连接池,它有啥好处?

python中实现mysql连接池

使用 Tomcat 进行连接池时出现 SQLNestedException

Tomcat 连接池问题 - 无法在关闭的连接上调用方法