简体   繁体   English

Mule ESB 3事务流单个Jdbc资源不回滚(MSSQL和jtds)

[英]Mule ESB 3 Transactional Flow Single Jdbc Resource Not Rolling Back (MSSQL & jtds)

EDIT : This only happens with MSSQL & jtds 1.2.6 Still investigating... 编辑 :这仅发生在MSSQL&jtds 1.2.6仍在调查中...
**Duplicate of : Mule 3.3.0 Jdbc Transaction Undesired Commit **重复: Mule 3.3.0 Jdbc事务不希望的提交
**Mule Documentation sucks. ** M鼠文档糟透了。

I want to rollback everything inside a flow that has several database endpoints. 我想回滚具有多个数据库端点的流中的所有内容。
I have a single JDBC datasource resource (ie no need for fancy XA, 2PC, etc). 我只有一个JDBC数据源资源(即不需要花哨的XA,2PC等)。
I have managed to configure Mule to, at least, not complain that no Transaction Manager is configured, etc.... but: It doesn't work; 我设法将Mule至少配置为不抱怨未配置任何事务管理器,等等。 ie it does not rollback the transaction when an exception occurs. 也就是说,当发生异常时,它不会回滚事务。
Since I'm running Mule standalone, I don't have fancy weblogic, jboss, etc transactionmanagers so I thought I could use Spring's DataSourceTransactionManager. 由于我是独立运行Mule的,所以我没有花哨的weblogic,jboss等事务管理器,因此我认为我可以使用Spring的DataSourceTransactionManager。 What other choice I have for this? 我对此还有什么选择?

Here is my flow (flow1 is just for triggering flow2, wich is the one I want to be transactional): 这是我的流程(flow1仅用于触发flow2,这是我要进行事务处理的流程):

流

And the XML: 和XML:

<?xml version="1.0" encoding="UTF-8"?>
<mule version="CE-3.3.0">
    <spring:beans>
        <spring:bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <spring:property name="dataSource" ref="dataSource" />
        </spring:bean>

        <spring:bean id="transactionFactory"
            class="org.mule.module.spring.transaction.SpringTransactionFactory">
            <spring:property name="manager" ref="transactionManager" />
        </spring:bean>

        <spring:bean id="dataSource" name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <spring:property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <spring:property name="url" value="jdbc:mysql://localhost/mydb"/>
            <spring:property name="username" value="sa"/>
            <spring:property name="password" value=""/>
        </spring:bean>    
    </spring:beans>

    <jdbc:connector name="jdbcConnector" dataSource-ref="dataSource"
        transactionPerMessage="true" queryTimeout="20000" pollingFrequency="10000"
        doc:name="Database" validateConnections="false"></jdbc:connector>
    <flow name="flow1" doc:name="flow1">
        <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
        <vm:outbound-endpoint exchange-pattern="request-response" path="toFlow2" doc:name="VM"/>
    </flow>
    <flow name="flow2" doc:name="flow2">
        <vm:inbound-endpoint exchange-pattern="request-response" path="toFlow2" doc:name="VM">
        <custom-transaction factory-ref="transactionFactory" action="ALWAYS_BEGIN" timeout="10"/>
    </vm:inbound-endpoint>
        <jdbc:outbound-endpoint exchange-pattern="request-response" queryKey="query1" queryTimeout="-1" connector-ref="jdbcConnector" doc:name="Database">
            <jdbc:query key="query1" value="insert into Foo (field1) values ('bar')"/>
            <jdbc:transaction action="ALWAYS_JOIN"/>
        </jdbc:outbound-endpoint>
        <jdbc:outbound-endpoint exchange-pattern="request-response" queryKey="query2" queryTimeout="-1" connector-ref="jdbcConnector" doc:name="Database">
            <jdbc:query key="query2" value="insert into Bar (field1) values ('foo')"/>
            <jdbc:transaction action="ALWAYS_JOIN"/>
        </jdbc:outbound-endpoint>
    </flow>

</mule>

Not shown here, I also have a default exception catch strategy, that simply writes the faulty payload to a file. 这里没有显示,我还有一个默认的异常捕获策略,可以将错误的有效负载简单地写入文件。 I don't know if I need to do a rollback explicitly, but I didn't find how. 我不知道是否需要显式执行回滚,但是我没有找到方法。

Any help would be much appreciated. 任何帮助将非常感激。

After two days of banging my head against Mule I finally managed to make this work. 经过两天与Mule的碰撞,我终于设法完成了这项工作。
Conclusions: 结论:

  • You need to use jTDS 's own DataSource (net.sourceforge.jtds.jdbcx.JtdsDataSource) 您需要使用jTDS自己的数据源(net.sourceforge.jtds.jdbcx.JtdsDataSource)
  • You need to use mule's TransactionFactory (org.mule.transport.jdbc.JdbcTransactionFactory) 您需要使用m子的TransactionFactory(org.mule.transport.jdbc.JdbcTransactionFactory)
  • You need to use the undocumented (or at least, under-documented) tag to start transaction 您需要使用未记录(或至少记录不足)的标记来开始交易
  • jTDS ando/or Mule sucks (I don't know who is responsible for this particular issue). jTDS ando /或Mule很烂(我不知道是谁负责这个特殊问题)。
  • Mule Documentation sucks big time: this and this Mule Documentation很烂: 这个这个
  • MuleStudio sucks big time (Sloooow, buggy, no way to wire transactions via the GUI, assertexceptions, flows gets messed up if you drag and drop scripts, etc, etc). MuleStudio花费大量时间(Sloooow,越野车,无法通过GUI进行交易,断言异常,如果拖放脚本会弄乱流程等)。

The final working flow: 最终的工作流程:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:jdbc="http://www.mulesoft.org/schema/mule/jdbc" xmlns:http="http://www.mulesoft.org/schema/mule/http"
    xmlns:vm="http://www.mulesoft.org/schema/mule/vm" 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="CE-3.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd 
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd 
http://www.mulesoft.org/schema/mule/jdbc http://www.mulesoft.org/schema/mule/jdbc/current/mule-jdbc.xsd 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd 
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd ">

    <spring:beans>
        <spring:bean id="jtdsDataSource" name="jtdsDataSource" class="net.sourceforge.jtds.jdbcx.JtdsDataSource">
            <spring:property name="user" value="your_user" />
            <spring:property name="password" value="your_password" />
            <spring:property name="databaseName" value="your_database" />
            <spring:property name="serverName" value="your_host" />
        </spring:bean>

        <spring:bean id="transactionFactory" name="transactionFactory" class="org.mule.transport.jdbc.JdbcTransactionFactory" />

    </spring:beans>

    <jdbc:connector name="dbConnector" dataSource-ref="jtdsDataSource" validateConnections="true" queryTimeout="-1" pollingFrequency="0" doc:name="Database" />

    <flow name="TriggerTxFlow" doc:name="TriggerTxFlow">
        <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" />
        <vm:outbound-endpoint exchange-pattern="request-response" path="toTxFlow" doc:name="VM" />
    </flow>
    <flow name="TxFlow" doc:name="TxFlow">
        <vm:inbound-endpoint exchange-pattern="request-response" path="toTxFlow" doc:name="VM">
            <custom-transaction factory-ref="transactionFactory" action="ALWAYS_BEGIN" timeout="10" />
        </vm:inbound-endpoint>
        <jdbc:outbound-endpoint exchange-pattern="request-response" queryKey="insert" queryTimeout="-1" connector-ref="dbConnector" doc:name="Database">
            <jdbc:transaction action="ALWAYS_JOIN" />
            <jdbc:query key="insert" value="insert into test values (1, 'Test 1')" />
        </jdbc:outbound-endpoint>
        <jdbc:outbound-endpoint exchange-pattern="request-response" queryKey="insert2" queryTimeout="-1" connector-ref="dbConnector" doc:name="Database">
            <jdbc:transaction action="ALWAYS_JOIN" />
            <jdbc:query key="insert2" value="insert into test values (2, 'Test 2')" />
        </jdbc:outbound-endpoint>
    </flow>
</mule>

In Mule you HAVE access to transaction managers. 在Mule中,您可以访问事务管理器。 For instance you can configure a jboss transaction manager by adding this to your configuration: 例如,您可以通过将jboss事务管理器添加到配置中来对其进行配置:

<jbossts:transaction-manager/>

A custom transaction is not required to work with XA. 使用XA不需要自定义事务。 You just have to use the xa-transaction element inside each endpoint instead. 您只需要在每个端点内使用xa-transaction元素即可。

Here you have your configuration updated to work with xa transactions in Mule. 在这里,您的配置已更新,可以在Mule中使用xa事务。

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

    <jdbc:connector name="jdbcConnector" dataSource-ref="dataSource"
        transactionPerMessage="true" queryTimeout="20000" pollingFrequency="10000"
        doc:name="Database" validateConnections="false">
    </jdbc:connector>

    <flow name="flow1" doc:name="flow1">
        <http:inbound-endpoint exchange-pattern="request-response" host="localhost"      port="8081" doc:name="HTTP"/>
        <vm:outbound-endpoint exchange-pattern="request-response" path="toFlow2" doc:name="VM"/>
    </flow>

    <flow name="flow2" doc:name="flow2">
        <vm:inbound-endpoint exchange-pattern="request-response" path="toFlow2" doc:name="VM">
            <xa-transaction action="ALWAYS_BEGIN" timeout="10"/>
        </vm:inbound-endpoint>
        <jdbc:outbound-endpoint exchange-pattern="request-response" queryKey="query1" queryTimeout="-1" connector-ref="jdbcConnector" doc:name="Database">
            <jdbc:query key="query1" value="insert into Foo (field1) values ('bar')"/>
            <xa-transaction action="ALWAYS_JOIN"/>
        </jdbc:outbound-endpoint>
        <jdbc:outbound-endpoint exchange-pattern="request-response" queryKey="query2" queryTimeout="-1" connector-ref="jdbcConnector" doc:name="Database">
            <jdbc:query key="query2" value="insert into Bar (field1) values ('foo')"/>
            <xa-transaction action="ALWAYS_JOIN"/>
         </jdbc:outbound-endpoint>
     </flow>

I agree that the documentation it's not as good as it should be but it's getting much better. 我同意它的文档虽然不尽如人意,但是它变得越来越好。 In fact the first page you mention has been rewriting from scratch. 实际上,您提到的第一页已经从头开始重写。

HTH, Pablo. HTH,Pablo。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM