Java Spring事务同步不工作(TransactionalEventListener)
我知道这个问题在这个网站上以稍微不同的形式被问到,但是按照这些帖子上给出的建议,我什么也做不到。我已经花了将近两天的时间在这上面,我已经没有主意了 我们有一个springbootmicro服务,它只监听进入ibmq队列的消息,进行一点转换并将其转发到Kafka主题。我们希望这是事务性的,这样就不会丢失任何消息(对我们的业务至关重要)。我们还希望能够对事务提交和回滚事件做出反应,以便进行监视和支持 我只是在互联网上遵循了一些“如何”的地方,我可以使用Java Spring事务同步不工作(TransactionalEventListener),java,spring,spring-boot,spring-transactions,Java,Spring,Spring Boot,Spring Transactions,我知道这个问题在这个网站上以稍微不同的形式被问到,但是按照这些帖子上给出的建议,我什么也做不到。我已经花了将近两天的时间在这上面,我已经没有主意了 我们有一个springbootmicro服务,它只监听进入ibmq队列的消息,进行一点转换并将其转发到Kafka主题。我们希望这是事务性的,这样就不会丢失任何消息(对我们的业务至关重要)。我们还希望能够对事务提交和回滚事件做出反应,以便进行监视和支持 我只是在互联网上遵循了一些“如何”的地方,我可以使用@transactional注释以声明的方式轻松
@transactional
注释以声明的方式轻松实现事务行为,如下所示:
@Transactional(transactionManager = "chainedTransactionManager", rollbackFor = Throwable.class)
@JmsListener(destination = "DEV.QUEUE.1", containerFactory = "mqListenerContainerFactory", concurrency = "10")
public void receiveMessage(@Headers Map<String, Object> jmsHeaders, String message) {
// Some work here including forward to Kafka topic:
// ...
// ...
// Then publish an event which is supposed to be acted on:
applicationEventPublisher.publishEvent(new MqConsumedEvent("JMS Correlation ID", "Message Payload"));
// Uncommented exception below to create a rollback scenario
// or comment it out to have the processing completed
throw new RuntimeException("No good Pal!");
}
这并没有发生。类似地注释掉在侦听器中抛出的异常,使得我们的MQ消息被传递给Kafka。但是,onCommit
方法不会执行
通过进一步的研究和spring调试,我相信这不会执行,因为spring认为在发布事件时没有活动事务,而我的事件只是被忽略了。评估TransactionSynchronizationManager.isActualTransactionActive()
并在日志中打印它会显示false
,这很难解释,因为正如我所说的,当故意抛出异常时,事务会按预期回滚
提前感谢您的投入
更新:
我放置的断点使我开始执行这个ApplicationListenerMethodTransactionalAdapter
类:
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (TransactionSynchronizationManager.isSynchronizationActive() &&
TransactionSynchronizationManager.isActualTransactionActive()) {
TransactionSynchronization transactionSynchronization = createTransactionSynchronization(event);
TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
}
else if (this.annotation.fallbackExecution()) {
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && logger.isWarnEnabled()) {
logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase");
}
processEvent(event);
}
else {
// No transactional event execution at all
if (logger.isDebugEnabled()) {
logger.debug("No transaction is active - skipping " + event);
}
}
}
因此,如果条件为假,我不理解第一个条件。然后回退执行是false
,因为我在@TransactionalEventListener
用法中没有将其设置为true
,它将在else分支上结束,并跳过事件
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (TransactionSynchronizationManager.isSynchronizationActive() &&
TransactionSynchronizationManager.isActualTransactionActive()) {
TransactionSynchronization transactionSynchronization = createTransactionSynchronization(event);
TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
}
else if (this.annotation.fallbackExecution()) {
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && logger.isWarnEnabled()) {
logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase");
}
processEvent(event);
}
else {
// No transactional event execution at all
if (logger.isDebugEnabled()) {
logger.debug("No transaction is active - skipping " + event);
}
}
}