【问题标题】:Transactions and Locking with Appengine使用 Appengine 进行事务和锁定
【发布时间】:2012-07-06 19:17:07
【问题描述】:

我在下面有一个类似的代码,我正在尝试找出事务锁定:

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,该 servlet 将删除 Points 实体,我预计删除操作将失败或至少在上述事务完成后删除实体。

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

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

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

使用 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 这样针对实体的新操作将等到当前操作在事务期间在实体上发生?

【问题讨论】:

    标签: google-app-engine objectify


    【解决方案1】:

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

    【讨论】:

    • 提交期间哪个事务被丢弃?先执行的还是后执行的?
    • @xybrek 第二个执行的那个 - 因为那个观察到底层数据在工作时被修改了。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 1970-01-01
      • 1970-01-01
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多