用物化创造或者犯错 [英] Create-or-Err with Objectify

查看:85
本文介绍了用物化创造或者犯错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始使用Google App Engine,并使用Objectify。如何在数据存储中创建根实体,但是如果它已经存在则是错误的?我没有找到任何内建的内容(例如 DatastoreService.put(),因此 ofy()。save()会覆盖现有的实体而不是err)。我习惯的简单技术就是在交易中这样做:


  1. 如果已经存在,则为Err

  2. 保存

然而,这不是幂等的;如果事务执行两次,它将在步骤1中发生错误。这是迄今为止最好的, 在交易中:


  1. 存在

  2. 保存

  3. 获取

  4. 如果它不是我们刚刚创建的数据, b

    $ b

    或者,如果我不介意两次保存相同数据的请求都成功,我可以跳过初始查找:
    $ b


    1. 提取

    2. 如果它与我们即将创建的数据相同,则报告成功

    3. 如果已经存在,但与我们即将创建的数据不同,则为Err
    4. 保存

    这是可行的,但它有点笨重,可以完成我认为是非常简单的操作。有没有更好的方法?

    解决方案

    这应该保证一致的行为:

      final String id = //选择唯一标识
    final long txnId = //选择一个uuid,时间戳,甚至是一个随机数

    )ofy()。transact(new VoidWork(){
    public void vrun(){
    Thing th = ofy()。load().type(thing.class).id(id).now ();
    if(th!= null){
    if(th.getTxnId()== txnId)
    return;
    else
    throw ThingAlreadyExistsException();


    th = createThing(id,txnId);
    ofy()。save()。entity(th);
    }
    }) ;


    I'm getting started with Google App Engine, and I'm using Objectify. How do I create a root entity in the data store, but err if it already exists? I didn't find anything built in for this (e.g. DatastoreService.put() and therefore ofy().save() will overwrite an existing entity instead of err). The simple technique I am used to is to do this in a transaction:

    1. Err if already exists
    2. Save

    However, that is not idempotent; it would err in step 1 if the transaction executes twice. Here is the best I've come up with so far, not in a transaction:

    1. Err if already exists
    2. Save
    3. Fetch
    4. Err if it's not the data we just created

    Or, if I don't mind two requests to save the same data both succeeding, I can skip the initial lookup:

    1. Fetch
    2. Report success if it's the same data we are about to create
    3. Err if already exists, but is not the same data we are about to create
    4. Save

    That is doable, but it gets a little bulky to accomplish what I thought would be a very simple operation. Is there a better way?

    解决方案

    This should guarantee consistent behavior:

    final String id = // pick the unique id
    final long txnId = // pick a uuid, timestamp, or even just a random number
    
    ofy().transact(new VoidWork() {
        public void vrun() {
            Thing th = ofy().load().type(thing.class).id(id).now();
            if (th != null) {
                if (th.getTxnId() == txnId)
                    return;
                else
                    throw ThingAlreadyExistsException();
            }
    
            th = createThing(id, txnId);
            ofy().save().entity(th);
        }
    });
    

    这篇关于用物化创造或者犯错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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