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,建议检查版本兼容性。
解决方案
- 修正实体类注解,明确指定序列名和分配大小,与数据库序列配置一致:
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_SEQ_generator") @SequenceGenerator(name = "order_SEQ_generator", sequenceName = "order_SEQ", allocationSize = 50) private long id;
- 检查Hibernate配置,确保启用新生成器:
hibernate.id.new_generator_mappings=true
- 验证订单表DDL,确保ID字段未配置
AUTO_INCREMENT,避免策略冲突。 - 若使用较旧版本MariaDB(如10.3之前),考虑升级至稳定版本排查bug。
内容的提问来源于stack exchange,提问作者Thomas

