Spring Integration-如果第一个事务失败,则回滚第二个事务

时间:2018-09-04 13:11:20

标签: transactions spring-data-jpa spring-integration

我必须将数据保存到2个不同的表中。我需要它是全有或全无的交易。如果第二笔交易失败,我该如何回滚第一笔交易?

在下面的代码中,我按以下顺序执行storeToTable1()和storeToTable2()。

如果storeToTable2()失败,我希望storeToTable1()回滚。

配置类:

class StoreToDBConfig {
    @Bean
        public IntegrationFlow receiveMessage() {
            return IntegrationFlows
                    .from("inputChannel")
                    .transform("convertToTable1Format")
                    .handle(ServicetoDBAdaptor,"storeToTable1")
                    .transform("convertToTable2Format")
                    .handle(ServicetoDBAdaptor,"storeToTable2")
                    .get();                 
        }
}

对数据库适配器的服务:

class ServicetoDBAdaptor {

@Autowired
UserExecutionDetail userExecutionDetail;

@Autowired
UserExecution userExecution;

@Autowired
UserExecutionDetailRepository userExecutionDetailRepository;

@Autowired
UserExecutionRepository userExecutionRepository;

@Transactional(propagation=Propagation.REQUIRED)
@ServiceActivator
private void storeToTable1(Message<UserExecutionDetail> msg) throws Exception {
    userExecutionDetailRepository.save(msg.getPayload());
}

@Transactional(propagation=Propagation.REQUIRED)
@ServiceActivator
private void storeToTable2(Message<UserExecution> msg) throws Exception {
    userExecutionRepository.save(msg.getPayload());
}
}

1 个答案:

答案 0 :(得分:2)

为此,您需要在第一个handle()上使用类似这样的内容:

.handle(ServicetoDBAdaptor,"storeToTable1", e -> e.transactional(true))

此钩子将完全执行此操作:

/**
 * Specify a {@link TransactionInterceptor} {@link Advice} with default
 * {@code PlatformTransactionManager} and {@link DefaultTransactionAttribute} for the
 * {@link MessageHandler}.
 * @param handleMessageAdvice the flag to indicate the target {@link Advice} type:
 * {@code false} - regular {@link TransactionInterceptor}; {@code true} -
 * {@link org.springframework.integration.transaction.TransactionHandleMessageAdvice}
 * extension.
 * @return the spec.
 */
public S transactional(boolean handleMessageAdvice) {

我们将在哪里使用这个

/**
 * A {@link TransactionInterceptor} extension with {@link HandleMessageAdvice} marker.
 * <p>
 * When this {@link Advice} is used from the {@code request-handler-advice-chain}, it is applied
 * to the {@link MessageHandler#handleMessage}
 * (not to the
 * {@link org.springframework.integration.handler.AbstractReplyProducingMessageHandler.RequestHandler#handleRequestMessage}),
 * therefore the entire downstream process is wrapped to the transaction.
 * <p>
 * In any other cases it is operated as a regular {@link TransactionInterceptor}.
 *
 * @author Artem Bilan
 *
 * @since 5.0
 */
@SuppressWarnings("serial")
public class TransactionHandleMessageAdvice extends TransactionInterceptor implements HandleMessageAdvice {

这里的关键是the entire downstream process is wrapped to the transaction.

因此,交易将从您的storeToTable1()开始,并且交易会一直扩展到流程结束,而您的storeToTable2()将参与同一TX。因此,当那个被回滚时,第一个也将被回滚。只是因为您根本只有一笔交易!