在Spring中将事务与异步事件同步

本文探讨了在Spring框架中如何处理事务与异步事件同步的问题。通过一个下订单并发送电子邮件的例子,展示了如何使用Spring的自定义事件避免事务延长。文章指出,默认情况下Spring事件处理是同步的,但可以通过配置使其变为异步。然而,这引入了竞态条件,可能导致事务一致性问题。解决方案包括使用TransactionSynchronizationManager注册提交后的侦听器,或者使用装饰器模式包装原始实现,确保消息发送在事务完成之后。这样可以解决竞争条件,保持代码可预测且无潜在错误。
摘要由CSDN通过智能技术生成

今天,我们以一个非常简单的场景为例:下订单将其存储并发送有关该订单的电子邮件:

@Service
class OrderService @Autowired() (orderDao: OrderDao, mailNotifier: OrderMailNotifier) {
 
    @Transactional
    def placeOrder(order: Order) {
        orderDao save order
        mailNotifier sendMail order
    }
}

到目前为止,一切都很好,但是电子邮件功能与下订单无关。 这只是一种分散注意力的副作用,而不是业务逻辑的一部分。 此外,发送电子邮件不必要地延长了交易时间并引入了延迟。 因此,我们决定使用事件将这两个动作分离。 为简单起见,我将利用Spring内置的自定义事件,但是我们的讨论与JMS或其他生产者-消费者库/队列同样重要。

case class OrderPlacedEvent(order: Order) extends ApplicationEvent
 
@Service
class OrderService @Autowired() (orderDao: OrderDao, eventPublisher: ApplicationEventPublisher) {
 
    @Transactional
    def placeOrder(order: Order) {
        orderDao save order
        eventPublisher publishEvent OrderPlacedEvent(order)
    }
 
}

如您所见,我们直接发送OrderPlacedEvent包装新创建的订单,而不是直接访问OrderMailNotifier bean。 发送事件需要ApplicationEventPublisher 。 当然,我们还必须实现客户端接收消息:

@Service
class OrderMailNotifier extends ApplicationListener[OrderPlacedEvent] {
 
    def onApplicationEvent(event: OrderPlacedEvent) {
        //sending e-mail...
    }
 
}

ApplicationListener[OrderPlacedEvent]指示我们感兴趣的事件类型。此方法有效,但是默认情况下,Spring ApplicationEvent是同步的,这意味着publishEvent()实际上正在阻塞。 知道Springÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值