【问题标题】:guava eventbus post after transaction/commit交易/提交后的番石榴事件总线发布
【发布时间】:2021-05-11 09:08:22
【问题描述】:

我目前在春季使用番石榴的事件总线,虽然目前一般功能运行良好,但我遇到了以下问题:

当用户想要更改“Line”实体上的数据时,这将在后端服务中照常处理。在此服务中,数据将首先通过 JPA 持久化,然后我创建一个“NotificationEvent”并引用已更改的实体。通过 EventBus,我将线路的引用发送给所有订阅者。

public void notifyUI(String lineId) {
    EventBus eventBus = getClientEventBus();
    eventBus.post(new LineNotificationEvent(lineId));
}

事件总线本身是在后台使用 new EventBus() 创建的。

现在在这种情况下,我的订阅者位于前端,在 @Transactional 领域之外。因此,当我更改数据时,发布事件并让订阅者从数据库中获取所有必要的更新,实际事务尚未提交,这使得订阅者获取旧数据。

我能想到的唯一快速解决方法是异步处理它并等待一两秒钟。但是在事务提交后,还有其他方法可以使用 guava 发布事件吗?

【问题讨论】:

    标签: spring guava event-bus


    【解决方案1】:

    我认为番石榴根本没有“意识到”春天,尤其是没有“@Transactional”的东西。

    因此,您需要一个创造性的解决方案。我可以考虑的一种解决方案是将此代码移动到您确定事务已完成的位置。 实现这一目标的一种方法是使用TransactionSyncrhonizationManager

    TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){
               void afterCommit(){
                    // do what you want to do after commit
                    // in this case call the notifyUI method
               }
    });
    
    

    注意,如果事务失败(回滚)该方法将不会被调用,在这种情况下您可能需要afterCompletion 方法。见documentation

    另一种可能的方法是将您的应用程序重构为以下内容:

    @Service
    public class NonTransactionalService {
    
       @Autowired 
       private ExistingService existing;
    
       public void entryPoint() {
    
          String lineId = existing.invokeInTransaction(...);
          // now you know for sure that the transaction has been committed
          notifyUI(lineId);
       }
    }
    
    @Service
    public class ExistingService  {
    
       @Transactional
       public String invokeInTransaction(...) {
          // do your stuff that you've done before
       }
    }
    
    

    我想在这里提到的最后一件事是,Spring 本身提供了一种事件机制,您可以使用它来代替 guava 的。

    例如见this tutorial

    【讨论】:

    • 嘿,谢谢您的解决方案,我也在考虑后者,只是方式不同。我会看看哪一个更适合我。我还阅读了 Spring 的 eventbus 实现,在我的简短研究中,我无法弄清楚如何创建自定义范围,因为我的应用程序有不同的客户端,需要非常严格地分开。使用番石榴我可以很容易地在工厂对象中做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多