我有一个API,它是用nodejs为GCP编写的。在日志中,有时API为前两个事务返回{"code":10,"rowCounts":[]},但所有其他事务都正常工作。
除了{"code":10,"rowCounts":[]}之外,错误中没有其他详细信息。
但如果我尝试这样做,请将此查询直接运行到扳手中。正在执行查询,没有任何错误。
我有以下交易代码:
database.runTransaction(async (err, transaction) => {
if (queries.length != 0) {
try {
await transaction.batchUpdate(queries);
transaction.commit(function(err) {
if (!err) {
console.log('transaction commited');
});
} catch (error) {
//I get the error here in transaction commit.
console.log(JSON.stringify(error));
return callback(some code);
}
}catch (error) {
console.log(JSON.stringify(error));
}
});
}
{code:10}表示中止[1]。理想情况下,我们的客户端应该处理此错误代码的重试。我在nodejs客户端[3]上提交了一个bug来跟踪这个问题。
同时,您可以简单地重试请求,它应该会成功。此处有重试中止交易的指南[2]
- https://github.com/grpc/grpc/blob/master/doc/statuscodes.md
- https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.Spanner.Data/api/Google.Cloud.Spanner.V1.html#retrying-中止的事务
- https://github.com/googleapis/nodejs-spanner/issues/738
看起来您在这里混合了回调和承诺,如果我正确阅读了代码,那么您的错误实际上源自batchUpdate
。我不确定这是否是在回调运行程序中使用promise的副作用,但你能试着像这个一样运行你的事务吗
try {
await database.runTransactionAsync(async transaction => {
await transaction.batchUpdate(queries);
return transaction.commit();
});
} catch (e) {
console.error(error);
}
如果您决定在runTransactionAsync
函数中添加错误处理,那么重新抛出您看到的任何ABORTED错误是很重要的,否则运行者将不知道这些错误,也不会触发重试。