当前位置: 首页 > 知识库问答 >
问题:

事务/提交后guava eventbus发布

郭元凯
2023-03-14

我目前正在Spring玩番石榴的eventbus,虽然一般功能运行良好,但到目前为止,我遇到了以下问题:

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

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

eventbus本身是在后台使用new eventbus()创建的。

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

我能想到的唯一快速解决方案是异步处理并等待一两秒钟。但是,在事务提交后,是否有另一种方法可以使用番石榴发布事件?

共有1个答案

孔欣可
2023-03-14

我认为番石榴根本没有“意识到”Spring,尤其是它的“@事务性”东西。

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

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

请注意,如果事务失败(回滚),则不会调用该方法,在这种情况下,您可能需要在完成方法之后使用。请参阅留档

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

@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的机制。

例如,请参阅此教程

 类似资料:
  • 一些背景知识,我在我的web应用程序中使用JPA/Hibernate/Spring,我也使用org。springframework。orm。jpa。支持OpenEntityManagerViewFilter和用于处理实体的扩展持久性上下文。 问题: > 使用find方法从数据库加载实体,实体存储在会话中 用户更改实体并点击保存 用户更改反映在会话中存储的实体上(在控制器中) 实体被发送到服务类中的

  • 我正在使用手动事务时插入/更新3个表。我想在事务提交后立即插入到历史表中。这意味着有3个操作(针对每个表),只有在提交这些操作之后,我才希望调用一个方法。 这是我的代码: 有什么post commit方法吗?如何在提交之后而不是持久之后调用方法?

  • 我在我的项目中做过类似的事情。我手动回滚事务,为此我插入了try-catch块并手动回滚catch块中的事务。现在我从method1调用method2,并将对象保存到method2()中的数据库中,但它不会将对象保存到数据库中。 我只是想知道什么是可能的解决方案,保存对象在方法2()在方法1()的faliure。 提前感谢。

  • 我不熟悉Hibernate,并且继承了使用它的代码库。未定义自动提交,因此默认情况下为false。不过,基于我提出的其他问题,答案表明,最佳做法是对代码进行标定,以便在开始事务时始终应该提交()或回滚()(多亏了Apostolos)。该代码库使用以下代码中的格式来表示Select语句。我打算将任何新代码正确地划分为commit()或rollback(),但我只是好奇使用下面的模型会产生什么后果。应

  • 我有以下问题: 我正在使用Spring MVC 4.0.5和Hibernate 4.3.5,我正在尝试创建一个Restfull Web应用程序。问题是,我想排除某些字段,使其无法序列化为 JSON,具体取决于使用方面在控制器中调用的方法。 我现在的问题是Hibrate不会在事务从方法返回后立即提交事务,而只是在序列化之前提交。 Controller.java Service.java 方面的建议执

  • 我的路线如下 我知道(A)处的JMS消费者将在每次轮询时分叉JMS事务,并附加到线程。(B)中的事务处理节点也将在交换到达那里并连接到线程后分叉JPA事务。 请在下面找到我的问题: > < li >能否将两个不同的事务附加到一个线程上(如上所示)? < li >如果是,哪一个应该被停职? < li> 上述路由的提交和回滚顺序应该是什么? 注:我没有从骆驼在行动第二版中找到任何明显的答案,所以请指导