如果我的事务成功完成,如何使用Spring Integration仅发送消息?
作者:互联网
我正在学习Spring Integration,并使用它在Grails中实现基本的电子邮件服务.我想做的是打电话给我的电子邮件服务,但只有在尝试成功发送电子邮件的交易成功后才发送电子邮件.尽管这是在Grails中完成的,但除了使用BeanBuilder DSL而不是XML配置之外,它实际上与常规的Spring应用程序没有什么不同.
无论如何,这是我对频道的配置:
beans = {
xmlns integration:'http://www.springframework.org/schema/integration'
integration.channel(id: 'email')
}
这是我的服务:
class MailService {
@ServiceActivator(inputChannel = "email")
MailMessage sendMail(Closure callable) {
//sending mail code
}
}
现在,我期望发生的事情是,当我将此MailService注入另一个服务并调用send mail时,它将在电子邮件频道中放置一条消息,该消息仅在我的交易完成后才会发布.使我相信这是UserProcess的部分:http://docs.spring.io/spring-integration/reference/html/transactions.html,该节指出用户启动的流程将具有Spring提供的所有事务性属性.
我正在尝试通过集成测试对此进行测试:
void "test transactionality"() {
when:
assert DomainObject.all.size() == 0
DomainObject.withNewTransaction { status ->
DomainObject object = buildAndSaveNewObject()
objectNotificationService.sendEmails(object) //This service injects emailService and calls sendMail
throw new Exception()
}
then:
thrown(Exception) // This is true
DomainObject.all.size() == 0 // This is true
greenMail.receivedMessages.length == 0 // This fails
}
这样做是创建和保存一个对象,然后在同一笔交易中发送电子邮件.然后,我引发异常以导致该事务失败.不出所料,我的域对象都没有持久化.但是,我仍然收到电子邮件.
我对Spring Integration和Spring总体而言还很陌生,因此可能会误解了这些工作原理,但是我希望sendMail消息永远不会放在电子邮件通道上.
解决方法:
我不知道如何在Grails中完成此操作,但是在Java中,您可以使用transaction synchronization factory,根据成功/失败,您可以采取不同的操作…
<int:transaction-synchronization-factory id="syncFactory">
<int:after-commit expression="payload.renameTo('/success/' + payload.name)" channel="committedChannel" />
<int:after-rollback expression="payload.renameTo('/failed/' + payload.name)" channel="rolledBackChannel" />
</int:transaction-synchronization-factory>
表达式求值的结果将发送到通道,您可以在其中使用出站邮件适配器.
标签:transactions,grails,spring,spring-integration 来源: https://codeday.me/bug/20191122/2057946.html