问题描述
我开始使用Google App Engine,并使用Objectify。如何在数据存储中创建根实体,但是如果它已经存在则是错误的?我没有找到任何内建的内容(例如 DatastoreService.put()
,因此 ofy()。save()
会覆盖现有的实体而不是err)。我习惯的简单技术就是在交易中这样做:
- 如果已经存在,则为Err
- 保存
然而,这不是幂等的;如果事务执行两次,它将在步骤1中发生错误。这是迄今为止最好的, 在交易中:
- 存在
- 保存
- 获取
- 如果它不是我们刚刚创建的数据, b
$ b或者,如果我不介意两次保存相同数据的请求都成功,我可以跳过初始查找:
$ b- 提取
- 如果它与我们即将创建的数据相同,则报告成功
- 如果已经存在,但与我们即将创建的数据不同,则为Err
- 保存
这是可行的,但它有点笨重,可以完成我认为是非常简单的操作。有没有更好的方法?
解决方案这应该保证一致的行为:
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 thereforeofy().save()
will overwrite an existing entity instead of err). The simple technique I am used to is to do this in a transaction:- Err if already exists
- 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:
- Err if already exists
- Save
- Fetch
- 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:
- Fetch
- Report success if it's the same data we are about to create
- Err if already exists, but is not the same data we are about to create
- 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); } });
这篇关于用物化创造或者犯错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!