两个实体是否会使用此端点写入数据存储?
Will two entities get written to datastore with this endpoint?
我有一个端点方法,它首先使用查询来查看是否存在具有特定参数的实体,如果不存在,它将创建它。如果存在,我想在变量中增加一个计数器:
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
}
我的问题是,如果有人单击按钮以非常快的速度执行具有相同参数的上述端点,会发生什么情况?两个相同的报告实体是否会写入数据存储区?我只想确保写了一个。
此代码本身并不安全,并且存在允许创建多个报告的竞争条件。
为了确保安全,您需要 运行 交易中的代码。这意味着您必须有一个祖先查询(或将其转换为简单的主键查找)。一种选择是为 Report 提供用户的 @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
}
});
我有一个端点方法,它首先使用查询来查看是否存在具有特定参数的实体,如果不存在,它将创建它。如果存在,我想在变量中增加一个计数器:
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
}
我的问题是,如果有人单击按钮以非常快的速度执行具有相同参数的上述端点,会发生什么情况?两个相同的报告实体是否会写入数据存储区?我只想确保写了一个。
此代码本身并不安全,并且存在允许创建多个报告的竞争条件。
为了确保安全,您需要 运行 交易中的代码。这意味着您必须有一个祖先查询(或将其转换为简单的主键查找)。一种选择是为 Report 提供用户的 @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
}
});