Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在使用Spring数据时,如何确定是否插入了duplicate?_Java_Spring_Oracle_Orm_Spring Data Jpa - Fatal编程技术网

Java 在使用Spring数据时,如何确定是否插入了duplicate?

Java 在使用Spring数据时,如何确定是否插入了duplicate?,java,spring,oracle,orm,spring-data-jpa,Java,Spring,Oracle,Orm,Spring Data Jpa,库-Spring数据JPA、Java8、JUnit-4(用于测试) 我有一个实体,让我们称它为信号量。有多台机器试图创建一行相同的信号量。我们只希望他们中的一个成功。下面是发生的情况- 信号量行有一个主键,始终为1 机器A使用Spring数据创建信号量并将其保存到DBsave 机器B认为它也在创建信号量,并调用save,但最终更新了它,而客户机代码不知道它。我可以检查是否存在,但这不能保证任何事情,因为两台机器都可以在其中任何一台创建记录之前进行检查 完成加工后,赢得镶件的机器将清理工作台 除了

库-Spring数据JPA、Java8、JUnit-4(用于测试)

我有一个实体,让我们称它为信号量。有多台机器试图创建一行相同的
信号量。我们只希望他们中的一个成功。下面是发生的情况-

  • 信号量
    行有一个主键,始终为1
  • 机器A使用Spring数据创建信号量并将其保存到DB
    save
  • 机器B认为它也在创建信号量,并调用save,但最终更新了它,而客户机代码不知道它。我可以检查
    是否存在
    ,但这不能保证任何事情,因为两台机器都可以在其中任何一台创建记录之前进行检查
  • 完成加工后,赢得镶件的机器将清理工作台
  • 除了直接使用实体管理器查看实体是否为新实体外,我们还有哪些选择?基本上覆盖Spring数据保存方法

    @Transactional
    public <S extends T> S save(S entity) {
        if(this.entityInformation.isNew(entity)) {
            this.em.persist(entity);
            return entity;
        } else {
            return this.em.merge(entity);
        }
    }
    
    我们使用Oracle作为数据库

    下面是Spring的
    SimpleParepository
    save方法,供大家参考

    @Transactional
    public <S extends T> S save(S entity) {
        if(this.entityInformation.isNew(entity)) {
            this.em.persist(entity);
            return entity;
        } else {
            return this.em.merge(entity);
        }
    }
    
    @Transactional
    公共存储(S实体){
    if(this.entityInformation.isNew(entity)){
    这个.em.persist(实体);
    返回实体;
    }否则{
    返回此.em.merge(实体);
    }
    }
    
    您需要的是乐观锁定,您可以通过在
    @Entity
    类中使用
    @version
    注释的版本字段来实现这一点

    例如


    下面是我们如何解决这个问题的方法

  • 不要在开始时使用Sprint数据的
    保存
  • 使用
    长版本
    上的
    @Version
    标记,将其归档到版本以进行乐观锁定
  • 使用标准弹簧数据
    findById
    查找记录。如果发现一个,我们会去更新它。如果更新失败,我们知道这台机器失去了它的出价,所以它放弃了
  • 如果没有找到记录,请使用JPA
    persist
    首先插入。如果persist失败,我们知道这台机器失去了它的出价,所以它放弃了
  • 整个过程被包装在一个
    @事务性
    注释中
    
  • 如果我们在这里,没有例外,我们知道我们有一个赢家。它继续进行并处理
    谢谢大家的帮助

    你有一些唯一性约束吗?啊,所以你依赖于PK。您是否可以添加另一个字段,其唯一目的是唯一性,但不会自动合并?使用
    Serializable
    隔离级别的事务如何<代码>@Transactional(隔离=隔离.SERIALIZABLE)
  • 。用这个注释您的服务层应该会锁定整个表。@Mikewjtyna问题是Spring数据JPA
    save
    将合并。我在发布我的答案后立即看到@Mikewjtyna的答案,乐观锁定的工作原理与他解释的完全一样。除非您在保存后刷新实体,否则它应该可以正常工作,因为两个并发事务都有相同的版本,只有一个会成功。乐观锁定不能立即工作,因为正如我上面解释的,Spring数据在保存之前会刷新。