【问题标题】:How to handle concurrent inserts in jpa如何在 jpa 中处理并发插入
【发布时间】:2021-01-26 22:41:55
【问题描述】:

我目前有多条消息在同一秒内到达。它们具有以下属性:

  1. 父密钥
  2. 说明
  3. 金额

逻辑如下:

  1. 在 key = ParentKey 的地方查找父项

    a) 如果 parent 不存在,则插入带有 key = ParentKey 的 parent

  2. 使用(id、parent_key、description、amount)插入孩子

现在的问题是,在并行处理中,我要么得到隔离级别 SERIALIZE 的异常(这是正确的吗?),要么得到父级的 UniqueConstraintViolation。

如果我对 key 没有唯一约束而只有一个序列号,我最终会得到多个条目。

有什么办法可以防止这种情况发生吗?或者任何重试机制?我只想为这个 id 插入一个。

【问题讨论】:

  • 很抱歉没有提供帮助,伙计:
  • @aran 如果我们始终与一个工人在一起,您的解决方案至少会奏效。我猜总比没有好。不要以为我会得到另一个答案,所以请随时发布
  • 如果使用读写锁,可能会解决问题。这意味着只有一个人会写,其他人可以读。

标签: java database hibernate


【解决方案1】:

我遇到了同样的情况。在我的情况下,我创建了另一个 ejb,其中 Transaction Attribute 设置为 REQUIRES_NEW 并在那里执行插入,然后在调用者 ejb 中捕获潜在的异常。然后在 catch 块中再次调用执行插入操作的 ejb。

如果您希望插入是与其他数据库更新活动相同的事务的一部分,则此方法可能不适用于所有情况。

【讨论】:

  • 如果您希望插入成为同一事务的一部分,请考虑在 Web 层重试。在您的 Restful API 接收器或 servlet 中,使用 try catch 块调用您的 EJB,该块执行所有数据库 DML 操作捕获异常并在那里重试。 Restful API/servlet 不应该是事务的一部分,只能在您的 ejb 中启动一个。
  • 如果您使用 JPA 实体管理器,您还可以使用blogs.oracle.com/enterprisetechtips/… 中描述的锁定模式。要启用锁定模式,您还需要有一个“版本”列来存储实体版本号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 2016-06-28
相关资源
最近更新 更多