gpt4 book ai didi

spring-data - 如何正确使用 Locking 或 Transactions 来防止使用 Spring Data 重复

转载 作者:行者123 更新时间:2023-12-03 19:54:13 25 4
gpt4 key购买 nike

检查记录是否存在,如果不存在,创建它(避免重复)的最佳方法是什么?
请记住,这是一个跨多个应用程序服务器运行的分布式应用程序。
我试图避免这些:

  • Race Conditions
  • TOCTOU

  • 一个简单的例子:
    Person.java
    @Entity
    public class Person {

    @Id
    @GeneratedValue
    private long id;

    private String firstName;

    private String lastName;

    //Getters and Setters Omitted

    }
    PersonRepository.java
    public interface PersonRepository extends CrudRepository<Person, Long>{

    public Person findByFirstName(String firstName);

    }
    一些方法
    public void someMethod() {
    Person john = new Person();
    john.setFirstName("John");
    john.setLastName("Doe");
    if(personRepo.findByFirstName(john.getFirstName()) == null){
    personRepo.save(john);
    }else{
    //Don't Save Person
    }
    }
    很明显,就目前的代码而言,在我检查它是否已经存在和我自己插入它的时间之间,有可能将 Person 插入到数据库中。因此将创建一个副本。
    我应该如何避免这种情况?
    根据我最初的研究,也许是
  • @Transactional
  • @Lock

  • 但确切的配置是我不确定的。任何指导将不胜感激。重申一下,此应用程序将分布在多个服务器上,因此它仍必须在高度可用的分布式环境中工作。

    最佳答案

    对于插入:如果您想防止保留相同的记录,那么您可能需要在 DB 端采取一些预防措施。在您的示例中,如果 firstname 应该是唯一的,则在该列上定义一个唯一索引,或者一组应该是唯一的 colunsd,并让 DB 处理检查,如果您插入记录,则只需插入并获取异常那已经插入了。

    更新:使用 @Version (javax.persistence.Version) 注释如下:

    @Version
    private long version;

    在表中定义一个 version 列,Hibernate 或任何其他 ORM 将在实体更新时自动填充该值并同时将 verison 填充到 where 子句。因此,如果有人尝试更新旧实体,则会阻止这种情况。请注意,这不会引发异常,只是将更新计数返回为 0,因此您可能需要检查一下。

    关于spring-data - 如何正确使用 Locking 或 Transactions 来防止使用 Spring Data 重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35280388/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com