希望有人能帮助指出我代码中的问题。
我有一个在事务外定义的查询,当它被执行时,它正确匹配数据库中的现有记录。
但是,在事务内部执行查询的那一刻,它无法匹配数据库中的现有记录,尽管它们存在。
这是代码,输出如下:
// Query for URL to see if any already exist
existingRemoteURLQuery := datastore.NewQuery("RepoStats").
Filter("RepoURL =", statsToSave.RepoURL).
KeysOnly().Limit(1)
testKey, _ := existingRemoteURLQuery.GetAll(ctx, new(models.RepoStats))
if len(testKey) > 0 {
log.Infof(ctx, "TEST Update existing record vice new key")
} else {
log.Infof(ctx, "TEST No existing key found, use new key")
}
// Check if we already have a record with this remote URL
var key *datastore.Key
err := datastore.RunInTransaction(ctx, func(ctx context.Context) error {
// This function's argument ctx shadows the variable ctx from the surrounding function.
// last parameter is ignored because it's a keys-only query
existingKeys, err := existingRemoteURLQuery.GetAll(ctx, new(models.RepoStats))
if len(existingKeys) > 0 {
log.Infof(ctx, "Update existing record vice new key")
// use existing key
key = existingKeys[0]
} else {
log.Infof(ctx, "No existing key found, use new key")
key = datastore.NewIncompleteKey(ctx, "RepoStats", nil)
}
return err
}, nil)
如您在输出中所见,事务外的第一个查询与现有记录正确匹配。但是在事务内部,它不识别现有记录:
2018/08/28 11:50:47 INFO: TEST Update existing record vice new key
2018/08/28 11:50:47 INFO: No existing key found, use new key
提前感谢您的帮助
已更新
Dan 的评论导致打印出交易内查询的错误消息:
if err != nil {
log.Errorf(ctx, "Issue running in transaction: %v", err)
}
打印:
ERROR: Issue running in transaction: API error 1 (datastore_v3: BAD_REQUEST): Only ancestor queries are allowed inside transactions.
最佳答案
将评论转化为答案
事实证明,当尝试在事务内执行非祖先查询时,这是特定于 go 的行为(FWIW,在 python 中尝试这样做实际上会引发异常)。
祖先查询是交易中唯一允许的查询。来自 What can be done in a transaction (不是很明确,恕我直言,因为查询可能会返回不符合交易限制的实体):
All Cloud Datastore operations in a transaction must operate on entities in the same entity group if the transaction is a single-group transaction, or on entities in a maximum of twenty-five entity groups if the transaction is a cross-group transaction. This includes querying for entities by ancestor, retrieving entities by key, updating entities, and deleting entities. Notice that each root entity belongs to a separate entity group, so a single transaction cannot create or operate on more than one root entity unless it is a cross-group transaction.
关于google-app-engine - Appengine Datastore 查询在事务中返回不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52057355/