Google App Engine原子部分? [英] Google App Engine atomic section?

查看:135
本文介绍了Google App Engine原子部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您从数据存储中检索一组记录(如:select * from MyClass where reserved ='false')。


  • 我如何确保另一个用户不会设置保留为false?

  • >我查看了交易文档,并从谷歌的解决方案中感到震惊,该解决方案捕获异常并在循环中重试。



    我错过的任何解决方案 - 很难相信在这个环境中没有办法进行原子操作。

    (顺便说一句 - 我可以在servlet中使用'syncronize',但我认为它是无效的因为没有办法确保只有一个servlet对象实例,不是吗?同样适用于静态变量解决方案)



    有关如何解决的任何想法?



    (以下是Google解决方案:

    http://code.google.com/appengine/docs/java/datastore/transactions.html#Entity_Groups



    看看:

      Key k = KeyFactory.createKey(Employee,k12345); 
    Employee e = pm.getObjectById(Employee.class,k);
    e.counter + = 1;
    pm.makePersistent(e);

    '这需要一个事务,因为该代码获取对象后可能会由另一个用户更新该值,但在保存修改的对象之前。没有事务,用户的请求将在其他用户更新之前使用计数器的值,并且保存将覆盖新值。通过交易,应用程序会被告知其他用户的更新。如果实体在事务期间更新,那么事务将失败并出现异常。

    可怕的解决方案,不是吗?

    解决方案

    你是正确的,你不能使用同步或静态变量。



    你是不正确的,它是不可能有一个原子动作在App Engine环境中。 (查看原子的含义此处)当您进行交易时,它是原子的 - 无论发生什么事,或什么都没有发生。这听起来像你想要的是某种全局锁定机制。在RDBMS领域,这可能类似于选择更新或将事务隔离级别设置为序列化事务。这两种类型的选项都不具备可扩展性。或者你会说,它们都是可怕的解决方案:)

    如果你真的想在应用程序引擎中进行全局锁定,你可以这样做,但它会变得丑陋和严肃损害可扩展性。所有你需要做的是创建一种CurrentUser实体,你可以在其中存储具有全局锁的当前用户的用户名。在让用户执行任何操作之前,您需要先检查没有用户已被列为CurrentUser,然后将该用户的密钥写入CurrentUser实体。支票和写入必须在交易中进行。这样,只有一个用户会成为当前,因此拥有全局锁定。


    • Say you retrieve a set of records from the datastore (something like: select * from MyClass where reserved='false').

    • how do i ensure that another user doesn't set the reserved is still false?

    I've looked in the Transaction documentation and got shocked from google's solution which is to catch the exception and retry in a loop.

    Any solution that I'm missing - it's hard to believe that there's no way to have an atomic operation in this environment.

    (btw - i could use 'syncronize' inside the servlet but i think it's not valid as there's no way to ensure that there's only one instance of the servlet object, isn't it? same applies to static variable solution)

    Any idea on how to solve?

    (here's the google solution:

    http://code.google.com/appengine/docs/java/datastore/transactions.html#Entity_Groups

    look at:

    Key k = KeyFactory.createKey("Employee", "k12345");
    Employee e = pm.getObjectById(Employee.class, k);
    e.counter += 1;
    pm.makePersistent(e);
    

    'This requires a transaction because the value may be updated by another user after this code fetches the object, but before it saves the modified object. Without a transaction, the user's request will use the value of counter prior to the other user's update, and the save will overwrite the new value. With a transaction, the application is told about the other user's update. If the entity is updated during the transaction, then the transaction fails with an exception. The application can repeat the transaction to use the new data'

    Horrible solution, isn't it?

    解决方案

    You are correct that you cannot use synchronize or a static variable.

    You are incorrect that it is impossible to have an atomic action in the App Engine environment. (See what atomic means here) When you do a transaction, it is atomic - either everything happens, or nothing happens. It sounds like what you want is some kind of global locking mechanism. In the RDBMS world, that might be something like "select for update" or setting your transaction isolation level to serialized transactions. Neither one of those types of options are very scalable. Or as you would say, they are both horrible solutions :)

    If you really want global locking in app engine, you can do it, but it will be ugly and seriously impair scalability. All you need to do is create some kind of CurrentUser entity, where you store the username of the current user who has a global lock. Before you let a user do anything, you would need to first check that no user is already listed as the CurrentUser, and then write that user's key into the CurrentUser entity. The check and the write would have to be in a transaction. This way, only one user will ever be "Current" and therefore have the global lock.

    这篇关于Google App Engine原子部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆