Подтвердить что ты не робот

Mule/Spring транзакция не распространяется

У меня проблема с транзакциями базы данных в потоке мула. Это поток, который я определил:

<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 beans:

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

В транзакции журнала транзакция выполняется одновременно, что означает, что эти транзакции создаются правильно, но выполняются одновременно, что вызывает проблему.

4b9b3361

Ответ 1

Проблема может быть вызвана многопоточным. Когда вы отправляете несколько объектов в виртуальную машину, они будут отправляться на несколько потоков приема и если многопоточность неправильно обрабатывается в ваших компонентах, вы можете столкнуться с проблемой, о которой вы упомянули.

Протестируйте эти изменения - добавьте ссылку на соединитель 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>

Помните о том, что, если количество входящих сообщений на виртуальной машине очень велико, а время, затрачиваемое на обработку каждого сообщения, больше, то вы можете столкнуться с ошибками SEDA-QUEUE из-за отсутствия доступности потоков.

Если без потоковой передачи ваш поток работает правильно, вам может потребоваться посмотреть, как ваши компоненты должны вести себя в многопоточности.

Надеюсь, что это поможет!