java - 使用 JPA(Hibernate 实现)和 MySQL 保证 FIFO

标签 java mysql hibernate jpa

我需要在 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/

相关文章:

java - Spring Quartz重新安排作业第一次执行两次

c# - 选择数据的最佳方式是什么

java - 使用 hibernate/spring 数据的三重分层实体映射会导致无限递归循环

java - hibernate - 表名定义

java - 您如何在蓝/绿部署中管理共享数据库?

java - $ 在 Java 类名中有什么影响

java - JVM类型签名的方法类型是什么

mysql - 使用起始日期和截止日期过滤记录

PHP 不会插入聊天消息

java - 修改hibernate中的映射表名称