我有一个端点方法,它首先使用查询来查看是否存在具有某些参数的实体,如果不存在,则会创建它。如果它存在,我想在变量中增加一个计数器:
Report report = ofy().load().type(Report.class)
.filter("userID", userID)
.filter("state", state).first().now();
if (report == null) {
//write new entity to datastore with userID and state
} else {
//increase counter in entity +1
report.setCount(report.count+1)
//save entity to datastore
}
我的问题是,如果有人点击按钮以非常快速的方式执行具有相同参数的上述端点,会发生什么?是否会将两个相同的报表实体写入数据存储区?我只想确保写一个。
答案 0 :(得分:1)
这个代码本身并不安全,并且具有允许创建多个报告的竞争条件。
为了确保安全,您需要在事务中运行代码。这意味着您必须具有祖先查询(或将其转换为简单的主键查找)。一种选择是向报告提供用户的@Parent
。那么你可以这样:
ofy().transact(() -> {
Report report = ofy().load().type(Report.class)
.ancestor(user)
.filter("state", state).first().now();
if (report == null) {
//write new entity to datastore with userID and state
} else {
//increase counter in entity +1
report.setCount(report.count+1)
//save entity to datastore
}
});