【发布时间】:2014-01-30 09:51:48
【问题描述】:
我们有一个实体定义为(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> 我们最终会得到一个唯一的实体
有人可以教我如何原子地添加重复检查吗?如果我将现有的实体检查代码移动到事务上下文中是否有帮助?
例如下面的代码会起作用吗?
/* 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();
}
}
}
}
如果我应该提供更多详细信息,请告诉我。
【问题讨论】:
-
这将需要对您的数据库设计进行一些重组,但是应用程序级别的唯一标识符是否可以接受?这将比 Person 类型的唯一性范围的更高开销执行得更好。见this recent StackOverflow discussion。
标签: google-app-engine objectify