我需要在 MySQL 中保留一个任务队列。从 DB 读取它们时,我必须确保顺序与它们保存的顺序完全相同。 一般来说,我更喜欢与数据库无关的解决方案(即纯 JPA),但添加一些 Hibernate 和/或 MySQL 的风格也是可以接受的。
我的(可能是幼稚的)第一个版本是这样的:
em.createNamedQuery("MyQuery", MyTask.class).setFirstResult(0).setMaxResults(count).getResultList();
MyQuery
没有任何“order by”子句,即它看起来像:
SELECT t FROM MyTasks
这种方法是否可以保证传入的结果/实体按照它们一直存在的方式排序?如果我也启用缓存会怎样?
我还想在任务实体中添加一个额外的字段,它是一个以毫秒为单位的时间戳(UTC from 1970-01-01)
,然后在查询中按它排序,但我可能会处于这样一种情况,即两个任务一个接一个地立即生成,并且它们具有相同的时间戳。
欢迎提出任何解决方案/想法!
编辑: 我刚刚意识到自动增量(至少在 MySQL 中)一旦达到最大值就会抛出异常,并且无法再插入。这意味着我不必担心数据库会重置计数器,并且我可以在查询中通过“自动递增”列显式排序。当然,我还有另一个问题要处理,即如果容量太大以至于 MySQL 中最大可能的无符号整数类型不够大,该怎么办,但这个问题不一定与我现在正在处理的问题相结合。
最佳答案
专注于纯 JPA 解决方案,导致实体 MyTasks must have a primary key我建议您使用序列生成器作为其主键,并使用键上的 order by 子句对查询结果进行排序。
例如:
@Entity
class MyTask {
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE)
private Long id;
您还可以使用@SequenceGenerator 指定数据库中定义的生成器,将其与数据库稍微收紧。
编辑:您是否看过用于设置时间戳的@PrePersist 选项?也许你可以将时间戳字段和id排序的生成和排序按这个顺序结合起来,所以时间戳冲突通过id比较来解决(这是唯一的)。
关于java - 使用 JPA(Hibernate 实现)和 MySQL 保证 FIFO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30045132/