使用应用引擎进行交易和锁定



我在下面有一个类似的代码,我试图弄清楚事务锁定:

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 秒。在那段时间之间,我有一个测试,它将调用另一个将删除Points实体的 servlet,我预计删除操作会失败,或者至少在上述事务完成后删除实体。

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

从那里,应用程序在我执行将删除上述代码中的实体的 servlet 后抛出" Entity not found"异常。

虽然我已经在使用 GAE 事务,但我认为我仍然缺少一些东西,这就是我的测试失败的原因。

从 Delete 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)将等到事务期间实体上发生当前操作?

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

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

最新更新