douzi2785 2018-08-28 11:59
浏览 46
已采纳

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

Hoping someone can help point out the issue in my code.

I have a query defined outside a transaction, and when it's executed, it correctly matches an existing record in the database.

However, the moment that query is executed inside a transaction, it fails to match the existing records in the database, despite the fact that they exist.

Here's the code, with output below:

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

As you can see in the output, the first query outside the transaction correctly matches the existing record. But inside the transaction, it doesn't recognize the existing record:

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

Thanks for any help in advance

Updated

Dan's comment lead to printing out the error message on the query inside the transaction:

    if err != nil {
        log.Errorf(ctx, "Issue running in transaction: %v", err)
    }

Which prints:

ERROR: Issue running in transaction: API error 1 (datastore_v3: BAD_REQUEST): Only ancestor queries are allowed inside transactions.

  • 写回答

1条回答 默认 最新

  • dronthpi05943 2018-08-28 12:28
    关注

    Converting a comment into an answer

    Turns out this is the go-specific behaviour when attempting to perform non-ancestor queries inside transactions (FWIW, in python attempting to do so actually raises an exception).

    Ancestor queries are the only queries allowed inside transactions. From What can be done in a transaction (not very explicit, tho, IMHO implicit as queries could return entities not meeting the transaction restrictions):

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥30 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)