mysql - JPA:手动递增,避免竞争条件(MySQL)

标签 mysql jpa race-condition

我认为我有一个相当简单的任务,即根据某些条件,在向表中添加新记录时手动递增 ID。

假设我有 Book 和 Chapter 表。 Chapter 具有自动递增的 ChapterId、BookId 和 ChapterNo 的外键。每次我向书中添加章节时,我希望 ChapterNo 为该章节所属的特定书籍增加一。

这可以通过简单的 SQL 语句来完成:插入章节 (BookId, ChapterNo) 值 (XXX, select max(ChapterNo) + 1 from chapter where BookId = XXX)。但是有没有一种方法可以在 JPA 中做到这一点并避免竞争条件(如果我先阅读 max ChapterNo 然后进行插入就会发生这种情况)

更新:到目前为止,我想到的唯一合理的解决方案是:实现负责递增 ChapterNo 的数据库触发器。那么至少我不需要在 JPA 端进行任何 native 查询

最佳答案

也许这不是完整的解决方案,但是 @OrderColumn 有一个 JPA 功能注释。

本质上,您使用一个列表来实现您的@OneToMany 关系,JPA 会将列表中元素的顺序保存在数据库的一个列中。应用于书籍和章节,它会是这样的:

@Entity
public class Book
{
    ...
    @OneToMany(mappedBy="book")
    @OrderColumn(name="chapterNo")
    private List<Chapter> chapters;
    ...
}

但请注意,如果列表中的某些元素发生变化,这可能会导致对顺序列进行多次更新。例如,如果您删除第一章然后保留这本书,则所有其他章节都将更新以反射(reflect)它们在列表中的新位置。此外,您无法直接访问要在查询中使用的 chapterNo 列,只能通过列表索引进行隐式访问。

关于mysql - JPA:手动递增,避免竞争条件(MySQL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16592232/

相关文章:

mysql - 带投影的条件查询不获取一对多集合

mysql - 需要在MySQL中编写多个SELECT语句

Mysql如何按最大日期时间减少行并按非唯一id分组

mysql - 竞争条件下的 INSERT-SELECT 和 UPDATE

dart - 多个Future/Timer同时完成时是否存在比赛条件

php - SELECT 查询输出每个结果六次

java - 在 roo 项目中使用 javax.persistence.Table @Table 注释,如何使用 maven(或 spring)从构建配置文件中设置架构?

java - 在同一事务中运行多个更新的引用约束违反

java - 为什么说SessionFactory是ConnectionProvider的客户端

mysql - 解决 rails 中的竞争条件(Y 中 X 的数量有限)