После прочтения о Google Datastore концепции/теории я начал использовать Go datastore packageDatastore: создать родительский и дочерний объект в транзакции группы объектов?
Сценарий: Виды User
и LinkedAccount
требуют, чтобы каждый пользователь имеет один или несколько связанных счетов (яй 3-й вход партии). Для сильной согласованности LinkedAccounts будут дочерними элементами связанного пользователя. Создание нового пользователя затем включает в себя создание как пользователя, так и LinkedAccount, а не только одного.
Создание пользователя похоже на идеальный вариант использования для транзакций. Если, скажем, создание LinkedAccount завершается неудачно, транзакция откатывается с ошибкой. В настоящее время это не представляется возможным. Цель состоит в том, чтобы создать родителя, а затем ребенка в транзакции.
Согласно документации
операций Всех Datastore в операции должны работать на лицах в ту же группу объектов, если сделка является одной транзакцией группы
Мы хотим, чтобы новый User
и LinkedAccount
быть в одной группе, поэтому мне кажется, что Datastore должен поддерживать этот сценарий. Я опасаюсь, что предполагаемое значение состоит в том, что операции с существующими объектами в одной и той же группе могут выполняться в одной транзакции.
tx, err := datastore.NewTransaction(ctx)
if err != nil {
return err
}
incompleteUserKey := datastore.NewIncompleteKey(ctx, "User", nil)
pendingKey, err := tx.Put(incompleteUserKey, user)
if err != nil {
return err
}
incompleteLinkedAccountKey := datastore.NewIncompleteKey(ctx, "GithubAccount", incompleteUserKey)
// also tried PendingKey as parent, but its a separate struct type
_, err = tx.Put(incompleteLinkedAccountKey, linkedAccount)
if err != nil {
return err
}
// attempt to commit
if _, err := tx.Commit(); err != nil {
return err
}
return nil
От library source его понятно, почему это не работает. PendingKey
не являются ключами, а неполные ключи не могут использоваться в качестве родителей.
Является ли это необходимым ограничением хранилища данных или библиотеки? Для тех, кто сталкивался с этим типом требований, вы просто пожертвовали сильной консистенцией и сделали оба вида глобальными?
Для Google-способности:
- датасторе: недействительный ключ
- датасторе: не может использовать pendingKey как тип * "google.golang.org/cloud/datastore" .key
Спасибо за ответ.Я полагаю, что мой вопрос действительно сводится к тому, что «готовые или неполные ключи могут использоваться как своего рода« обещание »в транзакции», и кажется, что ответ отрицательный. Я предпочитаю ваше предложение, используя AllocateIds bc. Мне бы хотелось, чтобы Datastore выбирал числовой идентификатор, но недостатком AllocateIds недоступно в транзакциях. Я изучу эти подходы и вернусь – dghubble
Да, это хороший способ подвести итог, и вы правы, что в настоящее время не поддерживается. Что касается AllocateIds: он не транзактивен в том смысле, что распределение не откат, если транзакция завершилась неудачей, но это не мешает вам позвонить, пока транзакция активна. Если транзакция не удалась, вы просто в конечном итоге выделяете идентификатор, который не используется - не имеет большого значения. –
В этот уик-энд я взял подход AllocateIDs к транзакциям, требующим завершения ключа, и решил, что мне вряд ли понадобится вернуть выделенные, но неиспользуемые идентификаторы, потому что пространство настолько велико. – dghubble