并发插入实体集合

时间:2015-06-23 11:16:35

标签: sql hibernate jpa

我在FamilyPerson之间进行了双向映射:

@Entity class Family {
    @OneToMany(mappedBy = "family", ...)
    Set<Person> persons;
    ...
} 

@Entity class Person {
    @ManyToOne
    Family family;
    ...
}

我的问题是我可以同时添加和/或删除集合中的元素,这会在更新中破坏原子性,因为添加新人会创建不会与其他插入冲突的INSERT INTO Person ...语句。 @Version字段无效,因为我没有将Family实体更新为表格中的行,只是逻辑上。

如何仅启用集合的原子更新?我已尝试使用Family加载LockMode.PESSIMISTIC_WRITEFamily可以同步Family本身的更新,但不允许读取 d3.select("svg") .append("foreignObject") .attr("width", 480) .attr("height", 500) 的第二级缓存。我更喜欢在数据库中使用谓词约束的乐观事务。

1 个答案:

答案 0 :(得分:2)

您可以使用OPTIMISTIC_FORCE_INCREMENT

entityManager.lock(family, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

这种方式将在相应的Family实体实例中检查并递增。

修改

由于您正在使用L2缓存,并且由于某种原因(错误,设计决策或仅缺少功能)Hibernate在强制增量后不更新L2缓存中的版本,您将不得不实际加载实体锁定一切正常工作:

entityManager.find(Family.class, id, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

但是,现在您必须注意保持一致并在更新它们之前始终以这种方式加载Family实体(以避免使用过时的版本值,因为L2缓存与数据库不同步)。

要解决此问题,您可以向Family实体添加人工列,例如lastUpdateTime或其他内容,并在不使用任何显式锁定的情况下更新Family实例。然后将进行常规版本检查,并且所有内容都将与L2缓存同步。