WildFly25+Infinispan缓存表索引重复创建及VERSION字段异常问题
WildFly25 + Infinispan 缓存配置问题解决
问题现象
- 分布式缓存写入数据时,
VERSION(timestamp列)值始终为-1,不符合递增版本号/时间戳的预期 - 服务器首次启动部署正常,但缓存表已存在时重启,会尝试创建已存在的索引(如
session_corporateEAR_3_10_ear_corporateInterface_3_10_war_times),导致应用部署失败
1. 修复VERSION列值为-1的问题
Infinispan的timestamp-column默认用版本号而非时间戳,但需要手动开启缓存的版本化机制。在<distributed-cache>节点中添加版本配置即可:
<distributed-cache name="corpapp-session-cache-web"> <!-- 开启版本化,让VERSION列自动递增 --> <versioning scheme="SIMPLE" /> <persistence> <string-keyed-jdbc-store> <data-source jndi-url="java:/jdbc/sessioncache" data-source="SessionCacheDS" dialect="POSTGRES" passivation="false" preload="false" purge="false" shared="true"/> <string-keyed-table drop-on-exit="false" create-on-start="false" prefix="session"> <id-column name="ID" type="VARCHAR(255)"/> <data-column name="DATA" type="BYTEA"/> <timestamp-column name="VERSION" type="BIGINT"/> <segment-column name="S" type="INT"/> </string-keyed-table> </string-keyed-jdbc-store> </persistence> </distributed-cache>
添加<versioning scheme="SIMPLE" />后,每次更新缓存条目时VERSION列会自动递增,不再固定为-1。
2. 解决重启重复创建索引的问题
问题出在create-on-start="false"仅控制表的创建,Infinispan仍会尝试自动生成索引。以下三种方案任选其一:
方案一:显式声明已存在的索引,禁止自动创建
在<string-keyed-table>里添加<index>节点,指定现有索引并设置create="false":
<string-keyed-table drop-on-exit="false" create-on-start="false" prefix="session"> <id-column name="ID" type="VARCHAR(255)"/> <data-column name="DATA" type="BYTEA"/> <timestamp-column name="VERSION" type="BIGINT"/> <segment-column name="S" type="INT"/> <!-- 声明已存在的索引,告诉Infinispan不要重复创建 --> <index name="session_corporateEAR_3_10_ear_corporateInterface_3_10_war_times" create="false"> <column name="VERSION"/> </index> <index name="session_corporateEAR_3_10_ear_corporateInterface_3_10_war_segment" create="false"> <column name="S"/> </index> </string-keyed-table>
方案二:改用create-table-if-not-exists控制DDL
把create-on-start="false"替换为create-table-if-not-exists="true",这样Infinispan只会在表不存在时创建表和索引,已存在则跳过:
<string-keyed-table drop-on-exit="false" create-table-if-not-exists="true" prefix="session"> <!-- 列配置保持不变 --> </string-keyed-table>
注意要确保数据库用户有查询表和索引的权限,否则Infinispan无法判断资源是否存在。
方案三:手动建表建索引,彻底禁用自动DDL
如果想完全掌控数据库结构,先手动创建表和索引,然后在配置里添加manage-as-singleton="true"(针对多节点共享存储场景),避免多节点同时执行DDL:
<string-keyed-jdbc-store> <data-source jndi-url="java:/jdbc/sessioncache" data-source="SessionCacheDS" dialect="POSTGRES" passivation="false" preload="false" purge="false" shared="true"/> <string-keyed-table drop-on-exit="false" create-on-start="false" prefix="session" manage-as-singleton="true"> <!-- 列配置保持不变 --> </string-keyed-table> </string-keyed-jdbc-store>
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

