我们有一个定义为(id, name, school, & OTHER-FIELDS)
的实体。
id
由数据存储区自动分配。
我们希望确保<name, school>
的组合在数据存储区中是唯一的。
我们的代码写得像这样:
/* First check uniqueness, then save */
public void savePerson(final Person newPerson) {
List<Person> existing = ofy().load().type(Person.clas)
.filter("name=", name)
.filter("school=", school)
.list();
if (existing == null || existing.isEmpty()) {
ofy.transact(new VoidWork() {
@Override
public void vrun() {
ofy.save.entity(newPerson).now();
}
}
}
}
但是如果同时发生多个相同的savePerson调用仍然会发生(不可避免地我们会遇到这种情况),重复检查将失败(我认为因为当他们开始调用savePerson()
时数据实际上没有保存) ,我们在AppEngine数据存储区中找到了最终具有相同<name, school>
组合的重复实体。
我们确实希望在我们的数据存储中确保<name, school
&gt;我们最终将拥有一个独特的实体
有人可以教我如何添加重复检查原子吗?如果我将现有的实体检查代码移动到交易上下文中会有帮助吗?
例如,以下代码是否有效?
/* Put filtering search into transaction too */
public void savePerson(final Person newPerson) {
ofy.transact(new VoidWork() {
@Override
public void vrun() {
List<Person> existing = ofy().load().type(Person.class)
.filter("name=", name)
.filter("school=", school)
.list();
if (existing == null || existing.isEmpty()) {
ofy.save.entity(newPerson).now();
}
}
}
}
如果我应该提供更多细节,请告诉我。
答案 0 :(得分:0)
为了做你想做的事情,如果已经有给定名字+学校并保存实体,则必须使用单一交易来阅读;否则,如果您有许多并发用户,您将结束重复。您可以只加载第一个实体,而不是加载整个列表[即第一()]。确保&#39; name&#39;和学校&#39;被索引(即@Index)。另请检查您是否在web.xml中有ObjectifyFilter。
但是请注意,同一所学校可能有两个同名的人,所以你应该添加另一种方法来区分人。