英文:
Unique email in Google Datastore
问题
我有一个包含Email
字段的User
实体。User
实体的ID是一个ULID,因为我想允许用户更改他们的电子邮件地址,但我希望确保电子邮件地址在CREATE
和UPDATE
时都是唯一的。
我正在使用Datastore事务。这是一个代码片段:
ctx := context.Background()
k := datastore.NameKey("User", user.ID, nil)
_, err := client.RunInTransaction(ctx, func(t *datastore.Transaction) error {
// 其他需要在事务中的操作
_, err = t.Put(k, user)
return err
})
return err
Email
字段已经建立了索引。有没有办法在事务中搜索当前用户的电子邮件地址?
*datastore.Transaction
没有GetAll
方法,所以我无法像这样运行查询:
datastore.NewQuery("User").Filter("Email =", user.Email)
我担心使用
client.GetAll(ctx, q, nil)
不能保证在事务中的隔离性。
英文:
I have a User
entity containing an Email
field. The User
entity id is a ULID, because I want to allow users to change their email addresses, but I want to ensure that the email address is unique on both a CREATE
and an UPDATE
.
I am using Datastore transactions. This is a code fragment:
ctx := context.Background()
k := datastore.NameKey("User", user.ID, nil)
_, err := client.RunInTransaction(ctx, func(t *datastore.Transaction) error {
// other stuff that needs to be in transaction
_, err = t.Put(k, user)
return err
})
return err
The Email
field is indexed. Is there any way to search the User
entity for the current user's email address as part of the transaction?
*datastore.Transaction
does not have a GetAll
method, so I cannot run a query like this:
datastore.NewQuery("User").Filter("Email =", user.Email)
I'm afraid that using
client.GetAll(ctx, q, nil)
will not guarantee isolation within the transaction.
答案1
得分: 4
简短的回答是不可以,除非你查询的是特定的实体组,否则不能将查询作为事务的一部分。全局查询始终是最终一致的。然而,将所有内容放在一个单一的实体组中可能会严重限制写入吞吐量。
一种解决方法是创建另一个种类(Kind),其中的实体将电子邮件地址映射到用户。然后,在一个事务中,你可以检查电子邮件实体,如果它不存在或指向错误的位置,可以将电子邮件实体和用户实体一起设置为一个事务。
英文:
The short answer is no, you cannot use a query as part of a transaction unless you are querying a specific entity group. Global queries are alway eventually consistent. However, to put everything in a single entity group would likely limit write throughput too much.
A workaround is you can have another Kind with entities that map email addresses to users. Then you can, in a transaction, check the email Entity and if it doesn't exist or it points to a bad location, set the email Entity and the user Entity all as a single transaction.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论