【问题标题】:Spring, JPA, Hibernate, increment/decrement variable by expected amountSpring,JPA,Hibernate,按预期数量递增/递减变量
【发布时间】:2020-01-03 06:24:35
【问题描述】:

我有一个名为 numberOfPeopleInteger 变量,它属于一个实体。如果有人加入系统或离开系统,numberOfPeople 应加或减 1。

以下是我如何做到的两个 sn-ps:

增量:

world.setNumberOfPeople(world.getNumberOfPeople() + 1);

递减:

world.setNumberOfPeople(world.getNumberOfPeople() - 1);

我注意到这会导致意外行为。有时变量会增加,有时会增加超过 1,有时会保持不变。

实现预期行为的最佳方法是什么?请注意,这些操作是作为更大方法的一部分发生的,并且此事务服务中正在进行其他事情(其他变量也正在修改)。

【问题讨论】:

    标签: spring hibernate jpa spring-data-jpa


    【解决方案1】:

    您可以使用AtomicInteger 来增加和减少整数值。

    //Initial value is 0
    AtomicInteger atomicInteger = new AtomicInteger();
    atomicInteger.set(world.getNumberOfPeople()); 
    

    或者

    //Initial value is getNumberOfPeople()
    AtomicInteger atomicInteger = new AtomicInteger(world.getNumberOfPeople());
    

    增量

    world.setNumberOfPeople(atomicInteger.incrementAndGet());
    

    递减

    world.setNumberOfPeople(atomicInteger.decrementAndGet());
    

    参考文献 Atomic Integer documentation

    【讨论】:

      【解决方案2】:

      您似乎遇到了lost update problem,如果同时有多个用户同时更新numberOfPeople,则可能会发生这种情况。

      如果World实体被多个用户同时更新的概率不是很高,解决这个问题的常用方案是使用乐观锁。 JPA 通过@Version 支持乐观锁定,您可以简单地将版本属性添加到World

       @Version
       private int version;
      

      网上有很多资源可以解释@Versionthis


      【讨论】:

      • 我会说这个值会不断变化。你仍然推荐这个而不是 Atomic 解决方案吗?
      • @yasgur99 我在评论中回答了您的问题,之前添加了评论。我不知道为什么它会消失/删除........
      • 我看到了,但没有仔细看。不知道为什么它消失了。即使该变量不断更新,tldr 也使用原子?
      • 我也不确定为什么它消失了......如果你的问题的根本原因真的是由于根更新,更改为使用 AtomicInteger 不会解决问题。 AtomicInteger 只有在多个用户更新同一个 World 实例时才能防止并发问题。但是在 JPA 中,即使只有一个 World DB 记录,多个用户也可以将自己的和单独的 World 实例加载到他们的 Hibernate 会话中以使用。
      • 如果我没记错的话,如果更新失败,那么事务就丢失了。该系统无法承受这种故障。您建议如何继续前进?
      猜你喜欢
      • 2022-11-30
      • 1970-01-01
      • 2021-06-22
      • 2020-06-30
      • 2011-10-15
      • 2018-09-03
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多