GridDB Java 客户端按行键查询刚插入的数据时为何返回 null?
如果 Users 的行键是第 0 列、类型为 INTEGER,且没有并发删除等干扰,示例写入后应当能读到该行。仅凭这段代码,无法确定偶发返回 null 的原因,也不能直接认定是缺少 commit()。
先确认自动提交是否被关闭
GridDB Java API 的 Container 默认启用自动提交,写操作结束时会自动提交。原代码没有调用 setAutoCommit(false),因此没有依据要求额外提交。相关行为见 GridDB Java API 文档。
如果实际程序在其他位置关闭了自动提交,可以按下面的方式在写入事务完成后显式提交,再通过另一个读取端验证:
// 仅用于明确采用手动提交的场景
container.setAutoCommit(false);
Row row = container.createRow();
row.setInteger(0, 1);
row.setString(1, "John");
container.put(row);
container.commit();
Row fetched = container.get(1);
这段代码明确了事务边界,但不能据此断言原问题已经解决。原示例使用同一个 Container 顺序写入和读取,与另一个连接读取未提交数据的情况不同,应分别排查。
检查容器的实际行键
Container<Integer, Row> 不会替现有容器创建行键,row.setInteger(0, 1) 也只是给第 0 列赋值。需要核对容器创建时的 schema,确认该列确实被设为行键。
可以先输出实际元数据,将以下代码放在已有的 store 初始化代码之后:
ContainerInfo info = store.getContainerInfo("Users");
if (info == null) {
throw new IllegalStateException("Container Users not found");
}
System.out.println("Row key columns: " + info.getRowKeyColumnList());
for (int i = 0; i < info.getColumnCount(); i++) {
ColumnInfo column = info.getColumnInfo(i);
System.out.println(i + ": " + column.getName()
+ " / " + column.getType());
}
对于原示例,应确认:
- 行键只有第 0 列。
- 第 0 列类型为
GSType.INTEGER,对应 Java 的Integer。 - 第 1 列类型为
GSType.STRING。
使用 ContainerInfo 创建容器时,setRowKeyAssigned(true) 会将第一列设为行键,具体示例见 GridDB 编程指南。检查已有容器时,应读取其实际 schema,不能只根据创建代码中的预期判断。
对无行键容器调用按键读取,或传入不匹配的键类型,按 API 约定可能抛出异常,不能把这些配置问题一概解释成返回 null。get(key) 返回 null 的含义是未找到目标行,相关约定见 GridDB Java API 文档。
用最小代码排查偶发问题
确认 schema 正确后,保留原来的顺序写入和读取,在未找到数据时直接抛出异常:
Container<Integer, Row> container = store.getContainer("Users");
if (container == null) {
throw new IllegalStateException("Container Users not found");
}
Row row = container.createRow();
row.setInteger(0, 1);
row.setString(1, "John");
container.put(row);
Row fetched = container.get(1);
if (fetched == null) {
throw new IllegalStateException("Row key 1 not found after put");
}
System.out.println(fetched.getString(1));
该片段假设使用刚获取、未被其他代码修改提交模式的容器对象,并沿用已有的异常处理和资源关闭逻辑。
如果仍然偶发失败,应记录同一次执行中 put 和 get 的时间、线程、容器名及完整异常,并检查:
- 是否有其他线程或程序删除该行,或重建容器。
- 实际写入端、读取端及查看数据的工具是否连接到同一集群、同一数据库。
- 实际代码是否复用了容器对象,或在封装层修改过事务模式、捕获并忽略了异常。
如果最小代码仍能复现,需要补充容器创建代码、客户端与服务端版本及对应日志。现有信息不足以将问题归因于某个版本缺陷或事务配置。
备注:内容仅供参考。
