【问题标题】:Mule / Spring transaction is not propagatedMule / Spring 事务未传播
【发布时间】:2018-01-15 16:05:37
【问题描述】:

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

<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 那样。这意味着事务没有正常工作。

更多信息:

createNewOnecheckIfExists 都有以下注释:

@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

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

【问题讨论】:

标签: java spring mule spring-transactions transactional


【解决方案1】:

问题可能是因为多线程。当您将多个对象发布到 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 错误。

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

希望对您有所帮助!

【讨论】:

  • 这无济于事,因为问题出在事务上,而不是线程上。如果所有更改都将在单个事务中提交,则多个线程不会导致问题,因为事务将使所有更改线程安全。这里的问题是每个 spring-object 都有不同的事务并且没有使用相同的事务。
  • 我试过这个但没有成功,问题仍然发生在该配置的事件中。日志中还有很多并发线程。
  • 您是否看到您的流程一次处理多个记录?对于入站 VM 上的事务,流应该使用同步策略,并且接收消息的线程也应该处理它。其他线程是什么?
  • 如果有多个线程处理事务,那么在与数据库交互时,有必要研究一下您使用的事务隔离。不同的事务隔离对于一个事务何时可以查看其他事务所做的更改具有不同的语义。根据多线程的使用,您可能需要不同的隔离级别。
  • 我一次向流发送多条消息,这些消息被异步处理pool-75-thread-2pool-75-thread-4。那我需要检查事务隔离。
猜你喜欢
  • 2017-11-22
  • 2014-06-22
  • 1970-01-01
  • 2016-02-14
  • 2011-09-20
  • 2012-05-27
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
相关资源
最近更新 更多