目前,我们有一个orderId,我们给用户带来好处(张贴)。有多个事件可以触发利益/公告。但是条件是只有一个事件应该被触发。因此,为了处理当前的请求,我们创建了一个布尔字段POSTING_EVENT_SENT,最初设置为false,之后,能够将其标记为true的人可以继续进行。
public boolean isOrderLockedAndUpdatedToTriggerPosting(String orderId, OrderStatus orderStatus) {
Query query = new Query();
query.addCriteria(Criteria.where(OrderConstants.ORDER_ID).is(orderId));
query.addCriteria(Criteria.where(OrderConstants.POSTING_EVENT_SENT).is(false));
Update update = new Update();
update.set(OrderConstants.ORDER_STATUS, orderStatus);
update.set(OrderConstants.UPDATED_AT, new Date());
update.set(OrderConstants.UPDATED_IP_BY, deploymentProperties.getServerIp());
update.set(OrderConstants.POSTING_EVENT_SENT, true);
update.set(OrderConstants.UPDATED_BY, OrderConstants.UPDATED_BY_WORKER);
UpdateResult result = mongoTemplate.updateFirst(query, update, OrderDetails.class);
return result.getModifiedCount() > 0;
}
这是代码试图执行的mongodb查询。
db.order.update({orderId : 123, paymentEventSent: false},{$set : {paymentEventSent: true}})
我们正在检查字段是否为假,然后将其标记为true。因此,理论上只有一个请求能够完成同样的任务,因为mongo查询是原子的。但是在我们的场景中,两个并发查询都成功地更新了记录。我们还缺什么?
发布于 2021-01-27 09:01:24
使用条件更新并检查更新文档的数量,以确定更新是否发生。
require 'mongo'
client = Mongo::Client.new(['localhost:14400'])
coll = client['coll']
coll.delete_many
coll.insert_one(foo: 1)
rv = coll.update_one({foo: 1}, '$set' => {foo: 2})
if rv.modified_count == 1
puts 'Updated'
end
rv = coll.update_one({foo: 1}, '$set' => {foo: 2})
if rv.modified_count == 1
puts 'Updated'
end
https://github.com/p-mongo/tests/blob/master/query-conditional-update/test.rb
https://stackoverflow.com/questions/65915366
复制相似问题