UserA和用户B分别和同时改变objectA.filedA objectA.filedB的。 因为他们没有改变同一个领域,人们可能会认为没有重叠。 这是真的吗? 或执行pm.makePersistnace()实际覆盖整个对象... 相关提示...GAE更新不同的领域相同的实体
回答
这是你正在设想的事情吗?
- 爱丽丝获取对象。 {a = 1,b =“Foo”}
- Bob检索对象。 {a = 1,b =“Foo”}
- Alice通过改变b来修改对象。 {a = 1,b =“Bar”}
- Bob通过更改a来修改对象。 {a = 2,b =“Foo”}
- Alice坚持她的对象副本。 {a = 1,b =“Bar”}
- Bob坚持他的对象副本。 {A = 2,B =“富”}
鲍勃的对象的副本将覆盖数据存储中的副本,因为他坚持他的整个对象,不只是他的一套改变字段。或者,一般来说,无论哪一个持续存在,都会在数据存储中保留整个对象的。
您可以通过在一个事务中运行他们的每一个GET-设置和持续运营的解决这个问题。 App Engine事务不会锁定整个对象在本地检索或修改,它们只会阻止其他用户持续存在。所以:
- Alice在事务中检索对象。 {a = 1,b =“Foo”}
- Bob在事务中检索对象。 {a = 1,b =“Foo”}
- Alice通过改变b来修改对象。 {a = 1,b =“Bar”}
- Bob通过更改a来修改对象。 {A = 2,B = “foo” 的}
- 爱丽丝尝试来持久对象,但不能,因为Bob有它在一个事务中打开。 Alice将通过结束她的交易并重试来捕获...
- 由于Alice完成了他的交易{a = 2,b =“Foo”},所以Bob坚持这个对象,没有问题
- Alice重新检索她的交易。 {a = 2,b =“Foo”}
- Alice通过改变b来修改对象。 {A = 2,B =“酒吧”}
- 爱丽丝仍然存在的对象,它的作品,因为没有其他人有开放的交易。 {A = 2,B =“酒吧”}
我没有绝对的把握哪些用户将得到异常,但只要他们愿意重试当他们看到它,他们就要最终能够对对象进行修改并坚持下去。
这就是所谓的Optimistic Locking。
感谢您的回答。 可惜makePersistence()实现是将WHOLE对象写入数据存储区,而不是写入已更改的字段。 这个事实实际上是强制GAE中的任何共享对象更新作为规则使用事务。 此外 - 在这种情况下,您必须实施“重试机制”作为可能发生的事务中的异常。
所以...更新在GAE任何共享的对象应该始终有这些额外:
- 做交易
- 内实现重试机制
大多数谷歌在自己的例子网站实际上没有考虑到这一点。仿佛他们假设大多数应用程序将无法使用共享对象
例如(http://code.google.com/appengine/docs/java/datastore/creatinggettinganddeletingdata.html):
public void updateEmployeeTitle(User user, String newTitle) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Employee e = pm.getObjectById(Employee.class, user.getEmail());
if (titleChangeIsAuthorized(e, newTitle) {
e.setTitle(newTitle);
} else {
throw new UnauthorizedTitleChangeException(e, newTitle);
}
} finally {
pm.close();
}
}
OR:
public void updateEmployeeTitle(Employee e, String newTitle) {
if (titleChangeIsAuthorized(e, newTitle) {
e.setTitle(newTitle);
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
pm.makePersistent(e);
} finally {
pm.close();
}
} else {
throw new UnauthorizedTitleChangeException(e, newTitle);
}
}
他们也没有处理'OverQuotaException's或'CapabilityDisabledException's,但这可能只是因为它会使这个例子太复杂而无用。事实是,大多数应用程序永远不会遇到这些问题,因为大多数应用程序不会那么频繁地使用,以至于同时编辑是一个问题。有些应用根本不编辑现有实体,只创建并显示它们。你的应用程序似乎需要考虑它,所以你已经研究过它是一件好事。 – 2010-04-07 16:55:06
此外,通过讨论有关问题回答自己的问题通常不是一个好主意。这就是你的问题或答案的意见。 – 2010-04-07 16:57:24
但随后代码不会很好地显示并难以阅读 – bach 2010-04-07 17:46:02
- 1. 实体框架中只更新实际更新的领域
- 2. 休眠更新特定实体领域
- 3. 是领域模型和实体模型相同
- 4. LINQ不同领域
- 5. 不同领域的Cookie
- 6. 生成不同ID的相同实体
- 7. REST:更新与不同领域的资源需要不同的用户权限
- 8. 合并相同的行,并显示在新列不同的领域在SQL
- 9. 使用单一的更新不同领域
- 10. 数据库建模 - 从概念上不同的实体几乎相同的领域
- 11. 更新相同的实例变量来自不同进程的
- 12. 原则2:选择实体领域,包括相关领域
- 13. 设置相同的属性更多的领域
- 14. 与实体领域
- 15. 结合不同领域
- 16. 使用GSON不同领域
- 17. 从某一领域,根据不同的内容,mofify,并将其存放在不同的新领域
- 18. 实体框架相同的实体
- 19. 很多领域具有相同属性
- 20. SQL查询等领域不同的领域
- 21. 如何更新MongoDB中一个领域中,具有相同价值的文件?
- 22. 在同一领域
- 23. 领域的数据同步不一致
- 24. 排序两个不同的领域
- 25. 寻找不同领域的最大值
- 26. Android领域查询不同的外键
- 27. 不同领域的案例陈述
- 28. 各个领域的不同分析仪
- 29. 设置龟能在不同的领域
- 30. 三个不同领域的独特
您可能需要使用“身份证”重新考虑和'name' - 它们都是App Engine中的保留字,并且不可修改。 – 2010-04-07 16:38:24
非常好的建议。重命名为a和b。我还会将用户A和用户B重命名为Alice和Bob,以避免更多混淆。 – 2010-04-07 16:48:52