【问题标题】:At what point can I trust that data has been saved to mysql?我在什么时候可以相信数据已保存到 mysql?
【发布时间】:2016-01-15 21:23:49
【问题描述】:

创建新对象“Order”后,我想获取其生成的 ID 并将其放入 AMQP 队列,以便工作人员可以用它做其他事情。工作人员获取生成的 ID(消息)并查找订单,但抱怨不存在任何记录,即使我刚刚创建了一个。我试图弄清楚在我将消息(生成的 ID)放入队列之前调用我的 .persist() 之后等待多长时间(我认为这不是一个好主意);让工作人员一遍又一遍地循环,直到mysql确实返回一条记录(我也不喜欢);或者在我知道数据在 mysql 中是安全的之后找到一个可以将消息放入队列的点(这听起来最好)。我认为它需要在任何 @Transactional 方法之外完成。

要从 mysql 中读回数据的 worker 是不同服务器上不同系统的一部分。那么我什么时候可以告诉worker数据在mysql中,以便它可以开始它的任务呢?

@Transactional 方法完成后,数据是否已写入 mysql,这是真的,我无法理解这一点。 多谢一百​​万。

【问题讨论】:

  • 数据库事务是一个相当广泛的主题,但是是的,在您尝试从另一个事务中读取数据之前,您需要确保正在写入数据的事务已经完成。当然,除非您的事务隔离是READ_UNCOMMITTED,但我们不要讨论这个。
  • 一旦你提交了事务,你的所有动作都保证被持久化并且对运行它们自己事务的其他进程可见。除非您使用 READ_UNCOMMITTED 作为您的事务隔离级别。
  • 我的问题更多地是指从队列中选择订单 ID 的工作人员完全是另一个系统的一部分 - 抱歉,我忘了在我的问题中提及。生病更新。
  • 您的 AMQP 队列是事务性的吗?队列中的持久化和发布项目可以独立于同一个事务,以便它们一起成功或失败。根据您的 JPA ID 生成类型,该 ID 将在持久后可用或需要设置刷新。

标签: java jpa spring-boot rabbitmq transactional


【解决方案1】:

是不是@Transactional方法完成后数据是 完成写入mysql,我无法理解这一点。 多谢一百​​万。

首先,正如 Kayamann 和 Ralf 在 cmets 中所写,当事务提交(结束)时,可以保证数据存储并可供其他进程使用

@Transactional 方法很容易理解。当您有@Transactional 方法时,这意味着容器(将实际调用该方法的应用程序)将在调用该方法之前开始事务,并在成功或错误的情况下自动提交或回滚事务。

如果我们有

@Transactional
public void modify(){
   doSomething();
}

当您在代码中的某处调用(或通过容器调用,例如由于某些绑定)时,实际情况如下

tx=entityManager.beginTransaction();
object.modify();
tx.commit();

其实很简单。这种方法意味着交易是Container Controlled

作为您的四种情况,为了让您的外部系统知道事务已经完成,您必须使用消息队列(您已经在使用的)以及某个 id 的事务已完成的消息,并且它可以开始处理东西,或使用不同的技术,例如 REST。

远程系统可以通过队列和 REST 服务向每个人发送各种事件的信号,因此没有区别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    • 2016-06-27
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    相关资源
    最近更新 更多