我正在尝试在扳手数据集之上构建基于游标的分页API。要做到这一点,我正在使用初始请求中的读取时间戳来检索数据,然后将其编码为一个游标,然后可以用来执行" Exact staleness" (https://cloud.google.com/spanner/docs/timestamp-bounds)读取后续的分页请求。
例如,对第一页的请求的处理类似于:
Transaction tx = spanner.singleUseReadOnlyTransaction();
tx.executeQuery(statement); // result set containing the first page of data
tx.getReadTimestamp(); // read timestamp that gets returned in a cursor
以后的请求:
Transaction tx = spanner.singleUseReadOnlyTransaction(TimestampBound.ofReadTimestamp(cursorTs));
我还希望在光标时间戳到期时向用户返回一条消息(链接到上面的文档说明它们有效约一个小时)并且为此我有以下代码:
try {
// process spanner result set
} catch (SpannerException e) {
if (ErrorCode.FAILED_PRECONDITION.equals(e.getErrorCode)) {
// cursor has expired, return appropriate error message
}
}
在针对长时间运行的扳手数据库进行手动测试时,此方法正常。但是,在我的测试代码中,我创建了一个扳手数据库,然后在测试完成后将其拆除,在这些测试中,当我使用一个绝对应该过期的读取时间戳(比如说超过一年)时,只会间歇性地抛出扳手异常。 。在没有抛出异常的情况下,我得到一个空结果集。如果我使用这个过期的读取时间戳在我的测试中向扳手发出多个请求,那么最终数据库似乎始终会抛出"失败的前置条件"错误。
新配置的扳手数据库是否需要这种行为?
答案 0 :(得分:1)
我认为这种行为的原因是因为您使用的是只读事务。如documentation中所述,只读事务始终在选定的点观察数据库的一致状态和事务提交历史。在您的情况下,数据库在测试完成之前和之后创建并拆除。因此,除非经过多次尝试,否则不会观察到事务提交历史记录。