Запрос Appengine Datastore возвращает другой результат внутри транзакции - PullRequest
0 голосов
/ 28 августа 2018

Надеясь, что кто-то может помочь указать на проблему в моем коде.

У меня есть запрос, определенный вне транзакции, и когда он выполняется, он правильно соответствует существующей записи в базе данных.

Однако в тот момент, когда запрос выполняется внутри транзакции, он не соответствует существующим записям в базе данных, несмотря на тот факт, что они существуют.

Вот код с выводом ниже:

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

Спасибо за любую помощь заранее

Обновлено

Комментарий Дэна привел к выводу сообщения об ошибке в запросе внутри транзакции:

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

Какие отпечатки:

ОШИБКА: ошибка в транзакции: ошибка API 1 (datastore_v3: BAD_REQUEST): внутри транзакций разрешены только запросы предков.

1 Ответ

0 голосов
/ 28 августа 2018

Преобразование комментария в ответ

Оказывается, это специфическое поведение при попытке выполнить запросы не-предков внутри транзакций (FWIW, в python, пытающихся это сделать, фактически возникает исключение).

Запросы предков являются единственными запросами, разрешенными внутри транзакций. От Что можно сделать в транзакции (не очень явно, хотя, IMHO, неявный, поскольку запросы могут возвращать объекты, не соответствующие ограничениям транзакции):

Все операции облачного хранилища данных в транзакции должны выполняться объекты в той же группе объектов, если транзакция является одной группой транзакция, или на объектах из максимум 25 групп объектов если транзакция является межгрупповой. Это включает запрашивает сущности по предку, извлекает сущности по ключу, обновление сущностей и удаление сущностей. Обратите внимание, что каждый корневой объект принадлежит к отдельной группе объектов, поэтому отдельная транзакция не может создавать или работать более чем с одним корневым объектом, если это не кросс-групповая транзакция.

...