Appengine 数据存储区查询 returns 事务内的不同结果

Appengine Datastore query returns different result inside transaction

希望有人能帮助指出我代码中的问题。

我在事务外定义了一个查询,当它被执行时,它与数据库中的现有记录正确匹配。

但是,在事务内部执行查询的那一刻,它无法匹配数据库中的现有记录,尽管它们存在。

这是代码,输出如下:

// 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.

将评论转化为答案

事实证明这是尝试在事务内执行非祖先查询时的特定行为(FWIW,在 python 中尝试这样做实际上会引发异常)。

祖先查询是交易中唯一允许的查询。来自 What can be done in a transaction(不是很明确,恕我直言,因为查询可能 return 不符合交易限制的实体):

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.