You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MariaDB序列生成ID与预期不符问题咨询

MariaDB序列生成ID不符合预期的原因分析

问题背景回顾

我们创建了一个MariaDB序列,配置如下:

CREATE SEQUENCE order_SEQ START WITH 7000000 INCREMENT BY 50 MINVALUE=7000000;

JPA实体类使用序列生成ID:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE) 
private long id;

启动数据库插入第一条数据后,序列的next_not_cached_value被设置为7050000,但后续插入时生成的ID为7049951,与预期的7050001不符。

原因分析

1. JPA注解未关联自定义序列

仅使用@GeneratedValue(strategy = GenerationType.SEQUENCE)但未指定sequenceName时,JPA(如Hibernate)会默认使用内置序列(比如hibernate_sequence),而非你创建的order_SEQ。如果默认序列的增量为1,就会生成连续数值,而非步长50的序列值。

2. Hibernate生成器配置与序列不匹配

即使关联了正确序列,若Hibernate的allocationSize未与序列的INCREMENT BY(50)一致,也会导致异常:

  • 若allocationSize设为50000,Hibernate会一次性获取一个序列值(比如7000000),然后自增1生成连续ID(7000000到7049999),这就会出现7049951这类非50倍数的数值。
  • 若allocationSize与序列步长不匹配,还会导致序列值被过度消耗,提前触发缓存预加载。

3. 误解next_not_cached_value的含义

你认为next_not_cached_value=7050000意味着下一个ID从7050001开始,这是错误的。这个参数是MariaDB的预取缓存标记,代表当前缓存的序列值耗尽后,下一批预取的起始值。当前缓存的可用值是7000000到7049950(共1000个,每个步长50),在此范围内的序列值会被优先使用,直到缓存用完才会加载下一批。

4. 存在其他ID生成策略冲突

如果订单表的ID字段配置了AUTO_INCREMENT(尽管你提供的message表没有,但订单表可能存在),或者应用中有手动生成ID的逻辑,会覆盖序列的生成结果,导致非预期ID。

是否属于异常问题

这不属于MariaDB的原生异常,大概率是配置不匹配导致的问题;若排除所有配置问题后仍出现此现象,可能是特定MariaDB版本的序列缓存bug,建议检查版本兼容性。

解决方案

  1. 修正实体类注解,明确指定序列名和分配大小,与数据库序列配置一致:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_SEQ_generator")
@SequenceGenerator(name = "order_SEQ_generator", sequenceName = "order_SEQ", allocationSize = 50)
private long id;
  1. 检查Hibernate配置,确保启用新生成器:
hibernate.id.new_generator_mappings=true
  1. 验证订单表DDL,确保ID字段未配置AUTO_INCREMENT,避免策略冲突。
  2. 若使用较旧版本MariaDB(如10.3之前),考虑升级至稳定版本排查bug。

内容的提问来源于stack exchange,提问作者Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 14:06:02