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

时间:2018-08-28 11:59:30

标签: 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)
    }

哪些印刷品:

  

错误:事务中正在运行的问题:API错误1(datastore_v3:BAD_REQUEST):事务中仅允许祖先查询。

1 个答案:

答案 0 :(得分:6)

将评论转换为答案

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

祖先查询是事务内部唯一允许的查询。从What can be done in a transaction(不是很明确,恕我直言,因为查询可能返回不符合事务限制的实体,所以恕我直言):

  

交易中的所有Cloud Datastore操作必须在   如果交易是单一组,则同一实体组中的所有实体   交易,或最多25个实体组中的实体   如果交易是跨组交易。这包括   按祖先查询实体,按键检索实体,   更新实体,并删除实体。请注意,每个根实体   属于单独的实体组,因此单个交易不能   创建或在多个根实体上操作,除非它是一个   跨组交易。