UserA和UserB分别同时更改objectA.filedA objectA.filedB。 因为它们不会改变相同的字段,所以可能会认为没有重叠。 真的吗? 或者pm.makePersistnace()的实现实际上覆盖了整个对象...... 很高兴知道...
答案 0 :(得分:1)
这是你想象的那样吗?
您可以通过在事务中运行每个get-set-and-persist操作来解决此问题。 App Engine事务不会锁定整个对象在本地检索或修改,它们只是阻止其他用户持久化。所以:
我不确定哪个用户会获得异常,但只要他们愿意在他们看到它时重试,他们都能够对对象做出更改并最终坚持下去。
答案 1 :(得分:0)
感谢您的回答。 遗憾的是,makePersistence()实现是将WHOLE对象写入数据存储区而不仅仅是已更改的字段。 这个事实实际上迫使GAE中的任何共享对象更新使用事务作为规则。 更进一步 - 在这种情况下,您必须实现“重试机制”作为事务中的异常。
所以...更新GAE中的任何共享对象应该总是有这些额外的东西:
Google网站上的大多数示例实际上都没有考虑到这一点。好像他们假设大多数应用程序不会使用共享对象
例如(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);
}
}