Mule / Spring事务不会传播

时间:2017-08-08 07:48:55

标签: java spring mule spring-transactions transactional

我在mule flow中遇到数据库事务问题。这是我定义的流程:

<flow name="createPortinCaseServiceFlow">
    <vm:inbound-endpoint path="createPortinCase" exchange-pattern="request-response">
        <custom-transaction action="ALWAYS_BEGIN" factory-ref="muleTransactionFactory"/>
    </vm:inbound-endpoint>

    <component>
        <spring-object bean="checkIfExists"/>
    </component>
    <component>
        <spring-object bean="createNewOne"/>
    </component>

</flow>

我们的想法是在 checkIfExists 中验证是否存在某些数据(在数据库中),如果它存在异常。如果不是,我们转到 createNewOne 并创建新数据。

问题

如果我们同时运行流程,则会在 createNewOne 中多次创建新对象,并且它们不应该在我们之前调用 checkIfExists 。这意味着交易无法正常运作。

更多信息:

createNewOne checkIfExists 都有以下注释:

@Transactional(propagation = Propagation.MANDATORY)

muleTransactionFactory 的定义如下

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="dataSource" ref="teleportNpDataSource"/>
    <property name="entityManagerFactory" ref="npEntityManagerFactory"/>
    <property name="nestedTransactionAllowed" value="true"/>
    <property name="defaultTimeout" value="${teleport.np.tm.transactionTimeout}"/>
</bean>

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

我设置了TRACE日志级别(如@Shailendra建议的那样),我发现事务在所有spring bean中重用:

00:26:32.751 [pool-75-thread-1] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Participating in existing transaction

在日志事务中同时提交事务,这意味着这些事务是正确创建的,但是并发执行会导致问题。

1 个答案:

答案 0 :(得分:3)

问题可能是因为多线程。当您将多个对象发布到VM时,它们将被分派到多个接收线程,如果组件中没有正确处理多线程,那么您可能会遇到您提到的问题。

测试进行这些更改 - 添加VM连接器引用并关闭调度程序线程配置文件。这样,VM将一次处理一个消息,因为只有一个调度程序线程。

<vm:connector name="VM" validateConnections="true" doc:name="VM"    >
        <dispatcher-threading-profile doThreading="false"/>
    </vm:connector>
    <flow name="testFlow8">
        <vm:inbound-endpoint exchange-pattern="one-way"  doc:name="VM" connector-ref="VM">
            <custom-transaction action="NONE"/>
        </vm:inbound-endpoint>
    </flow>

请注意,如果VM上的传入消息数量非常高并且处理每条消息所需的时间更长,那么由于没有线程可用性,您可能会遇到SEDA-QUEUE错误。

如果没有线程,您的流程表现正常,那么您可能需要查看组件在多线程中的行为方式。

希望这有帮助!