我正在做一个在集群环境中运行的项目,那里有许多节点和一个数据库。该项目使用Spring-data-JPA(1.9.0)和Hibernate(5.0.1)。我有问题解决如何防止重复行问题。
举个例子,这里有一个简单的表
@Entity
@Table(name = "scheduled_updates")
public class ScheduledUpdateData {
public enum UpdateType {
TYPE_A,
TYPE_B
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private UUID id;
@Column(name = "type", nullable = false)
@Enumerated(EnumType.STRING)
private UpdateType type;
@Column(name = "source", nullable = false)
private UUID source;
}
重要的部分是有一个UniQUE(类型,源)
约束。
当然,匹配示例存储库:
@Repository
public class ScheduledUpdateRepository implements JpaRepository<ScheduledUpdateData, UUID> {
ScheduledUpdateData findOneByTypeAndSource(final UpdateType type, final UUID source);
//...
}
本例的思想是,系统的某些部分可以插入行,以便为周期性运行的内容进行调度,在所述运行之间可以进行任意次数的调度。当某个东西实际运行时,它不必担心在同一个东西上运行两次。
如何编写将有条件地插入到此表中的服务方法?我尝试过的一些不起作用的事情是:
>
@Repository
public class ScheduledUpdateRepository implements JpaRepository<ScheduledUpdateData, UUID> {
// ...
@Modifying
@Query(nativeQuery = true, value = "INSERT INTO scheduled_updates (type, source)" +
" SELECT :type, :src" +
" WHERE NOT EXISTS (SELECT * FROM scheduled_updates WHERE type = :type AND source = :src)")
void insertUniquely(@Param("type") final String type, @Param("src") final UUID source);
}
不幸的是,这也不起作用,因为Hibernate似乎首先自己执行WHERE
子句使用的SELECT
,这意味着最后会尝试多个插入,从而导致唯一的约束冲突。
我肯定不知道JTA、JPA或Hibernate有多少更好的优点。关于如何跨多个JVM插入具有唯一约束(不仅仅是主键)的表,有什么建议吗?
使用Postgres(2.3)作为数据库,尝试使用隔离级别SERIALIZABLE-遗憾的是,这本身仍然会导致约束冲突异常。
寻找
为什么这不起作用?
你考虑过“乐观锁定”吗?
这两个职位可能会有所帮助:
>
https://www.baeldung.com/jpa-optimistic-locking
https://www.baeldung.com/java-jpa-transaction-locks
这听起来像是一个突起的情况,可以按照这里的建议来处理。
Hibernate及其查询语言支持插入语句。因此,您实际上可以使用HQL编写该查询。更多信息请看这里。http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#_hql_syntax_for_insert
问题内容: 我在形成条件插入时遇到困难 我有x_table的列(实例,用户,项目),其中实例ID是唯一的。我只想在用户已经没有给定项目的情况下插入新行。 例如,尝试插入instance = 919191 user = 123 item = 456 朝正确方向的任何帮助或指导将不胜感激。 问题答案: 如果您的DBMS在执行插入操作时不限制从哪个表中选择,请尝试: 在这里,是一个只有一行的表(最初在O
我需要创建一个在表中插入或不插入数据的条件。有11个字段,从6到11,用户可以填写,也可以不填写。如果没有,它就不能保存此表中的任何数据。代码已创建,但正在进行插入。有人知道怎么修理吗?谢谢!
问题内容: 如何停止MySQL中的竞争条件?当前的问题是由一个简单的算法引起的: 从表中选择一行 如果不存在,将其插入 然后会得到重复的行,或者如果您通过唯一/主键阻止它,则会出现错误。 现在,通常我认为事务在这里有所帮助,但是由于该行不存在,所以事务实际上并没有帮助(或者我是否错过了什么?)。 LOCK TABLE听起来有些矫kill过正,尤其是如果该表每秒更新多次。 我唯一想到的其他解决方案是
问题内容: 是否有只查询记录的查询,如果不存在,则插入?我不想重复更新或替换。寻找一个查询解决方案,寻找其他答案,但不是我真正想要的。 表: 伪查询: 问题答案: 使用-与INSERT完全相同,不同之处在于,如果表中的旧行与PRIMARY KEY或UNIQUE索引的新行具有相同的值,则在插入新行之前会删除该旧行。 http://dev.mysql.com/doc/refman/5.0/en/rep
我知道jOOQ将在不支持它的系统(如PostgreSQL)上模拟SQLMERGE。 我有一个带有串行(自动增量)id列和字符串uri列的表。我想在我的数据库中使用数字ID而不是URI,所以我必须确保在ID查找表中有一个URI。因此,按照jOOQ手册中的示例,我认为这将起作用: 这给了我一个这样的语句: 但是日志说jOOQ继续并尝试用绑定值执行查询。但是该表从未更新。所以我猜jOOQ没有在Postg
我需要 在Hibernate条件中。由于这个问题,我知道如何将分组结果作为的列表: 我不知道如何添加HAVING子句。我想,它类似于,但是我如何引用计数呢? 有没有办法在查询中引用结果元组元素?