google-app-engine - Appengine Datastore 查询在事务中返回不同的结果

标签 google-app-engine go google-cloud-datastore

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

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

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

这是代码,输出如下:

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

相关文章:

arrays - 如何在golang中gzip字符串并返回字节数组

python - 在 Google DataStore 上使用限制/偏移量时获取总行数

google-app-engine - 使用自定义域和 HTTPS 的 App Engine 访问服务

java - Google Blobstore App Engine 教程

javascript - 如何修改上传功能的前端代码

javascript - 谷歌数据存储查询中的多项选择抛出 ApiError : Precondition Failed error in node

google-app-engine - GAE事务失败和幂等性

python - 获取文件的公共(public) URL - Google Cloud Storage - App Engine (Python)

python - 谷歌应用程序引擎 urlfetch gzip 到字符串

xml - 使用属性解码 xml 标签