Jpa,SpringData并发问题

时间:2018-07-10 16:32:40

标签: hibernate jpa concurrency spring-data aop

我有两个端点用于编辑同一实体(Foo),一个端点用于属性A,第二个端点用于属性B。

  

/ api / v2 / foo / {foo_id} / a / {value}

     

/ api / v2 / foo / {foo_id} / b / {value}

@Entity
Class Foo {

  // id, properties

  @OneToOne
  private Bar bar;
}

和嵌套类

@Entity
Class Bar {
  private String a;
  private String b;
}

此终结点在实体Foo的服务中执行并发操作

@Service
public class FooService{
  @Autowired
  private FooRepository fooRepository;

  void updateA(ADto adto){
    Foo tmp = fooRepository.findById(adto.getId());
    doLogic...
    fooRepository.saveAndFlush(tmp);
  }

  void updateB(BDto bdto){
    Foo tmp = fooRepository.findById(bdto.getId());
    doLogic...
    fooRepository.saveAndFlush(tmp);
  }
}

这两个调用是并发的,我的数据已损坏。 试图放入Foo实体

@Version
private Integer version;

尝试保存第二个电话时出现异常。 我要实现的目标是,如果保存由于并发而无法刷新域以刷新最新版本并保存更改,那么我将保存域。

有人可以向我建议一些方法吗?

2 个答案:

答案 0 :(得分:0)

如果要更新其他字段,也许应该尝试使用@DynamicUpdate。

答案 1 :(得分:0)

避免并发请求导致数据损坏的方法是使用数据库事务。

发布的代码未显示任何内容来指示您的交易边界在哪里。交易是否在您的存储库中?也许您开启了自动提交功能?无论如何,您都需要在服务层中实现事务处理。

  • 将@Transactional添加到服务类。检查这是spring注释,而不是javax注释。

  • 检查您的JPA提供程序的配置,以确保自动提交已关闭。

  • 检查版本字段是否映射到数据库列。