2012-07-06 166 views
1

锁定我有低于类似的代码,我试图找出事务锁:交易与AppEngine上

DAOT.repeatInTransaction(new Transactable() { 
     @Override 
     public void run(DAOT daot) 
     { 
       Points points = daot.ofy().find(Points.class, POINTS_ID); 
       // do something with points 
       takes_a_very_long_time_delay(); // perhaps 10 secs 
       daot.ofy().put(points); 
     } 
}); 

以上是从一个Java servlet中执行的代码。例如,该操作预计可以工作10秒钟。在那段时间之间,我有一个测试会调用另一个servlet,它会删除一个Points实体,我期待删除操作会失败,或者至少在上述事务完成后删除实体。

但是,在上述代码执行期间,实体被删除。在我的真实应用程序中,我尝试访问或编辑不存在的实体时添加了异常处理以引发异常。

从那里,应用程序就在我执行,将在上面的代码删除实体在servlet抛出“Entity not found"例外。

虽然我使用GAE交易已经,但是我觉得我还是失去了一些东西这就是为什么我的测试失败

代码为删除事务从withing删除的servlet:

DAOT.repeatInTransaction(new Transactable() { 
     @Override 
     public void run(DAOT daot) 
     { 
       Points points = daot.ofy().find(Points.class, POINTS_ID); 
       daot.ofy().delete(points); 
     } 
}); 

我怎样才能确保像delete为f的新的操作或者一个实体将在交易期间等到当前操作发生在一个实体上?

回答

5

App Engine使用乐观并发性,而不是锁定。也就是说,一组实体上的事务不会阻止其他进程在事务运行时修改这些实体。相反,当事务尝试提交时,它将检查在事务执行时是否进行了修改,如果有,则从一开始就放弃所有更改并再次运行您的函数。

+0

在提交期间丢弃哪个事务?一个是执行第一个还是第二个执行? – xybrek 2012-07-10 06:52:36

+4

@xybrek第二个被执行的人 - 因为观察底层数据的人在工作时被修改过。 – 2012-07-10 09:05:53

1

我假设你使用objectify来处理数据存储。 首先,您需要确保daot.ofy()返回具有显式事务集(ObjectifyFactory.beginTransaction())的Objectify实例,而不是ObjectifyFactory.begin()。然后确保对find()和delete()调用(以及find()/ put对)使用相同的对象化实例。