Прочитав о концепциях / теории Google Datastore, я начал использовать пакет хранилища данных Go а>
Сценарий: Виды User
и LinkedAccount
требуют, чтобы у каждого пользователя была одна или несколько связанных учетных записей (yay сторонний вход). Для большей согласованности LinkedAccounts будет дочерним элементом связанного пользователя. Затем создание нового пользователя включает в себя создание как пользователя, так и LinkedAccount, а не только одного.
Создание пользователей кажется идеальным вариантом использования для транзакций. Если, скажем, создание LinkedAccount не удалось, транзакция откатится и завершится ошибкой. В настоящее время это не представляется возможным. Цель состоит в том, чтобы создать в транзакции родителя, а затем потомка.
Согласно документам
Все операции с хранилищем данных в транзакции должны работать с объектами в одной группе объектов, если транзакция является одной групповой транзакцией.
Мы хотим, чтобы новые User
и LinkedAccount
находились в одной группе, поэтому мне кажется, что хранилище данных должно поддерживать этот сценарий. Я опасаюсь, что предполагаемое значение состоит в том, что операции с существующими объектами в одной группе могут выполняться за одну транзакцию.
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
Из источника библиотеки становится ясно, почему это не работает. PendingKey
не являются ключами, а неполные ключи нельзя использовать в качестве родительских.
Это необходимое ограничение хранилища данных или библиотеки? Для тех, у кого есть опыт работы с требованиями такого типа, неужели вы просто пожертвовали строгой согласованностью и сделали оба вида глобальными?
Для Google-способности:
- хранилище данных: неверный ключ
- хранилище данных: нельзя использовать pendingKey как тип * "google.golang.org/cloud/datastore" .Key