ravendb - 仅当值尚不存在时,如何将值添加到集合中?
问题描述
在 ravendb 中,我试图解决一个竞争条件,即多个 url 可以同时添加到单个文档中。为了安全地执行此操作(并且不在集合中创建重复条目),我需要条件检查和数组推送在数据库中以原子方式发生。例如,结构可能如下所示:
public class MyData
{
public string Id { get; set; }
public List<string> Urls { get; set; }
}
假设所有这三个操作都是异步发生的:
AddValue("foo");
AddValue("bar");
AddValue("foo");
我在看补丁,但我没有看到如何添加条件。有人可以给我举个例子来说明我可以如何做到这一点吗?
更新
这是我目前正在使用的
var listing = _session.Query<ListingData>()
.Where(l => l.ListingId == listingId && l.OwnerId == userId)
.ToList().SingleOrDefault();
if (listing == null)
return DataResult.NotFound;
_session.Advanced.Patch(
listing,
l => l.PhotoUrls,
urls => urls.Add(url));
_session.SaveChanges();
如果一切顺利,这似乎暂时有效,但如果有一些情况,例如,基于假阴性的应用程序端重试发生,那么我认为我最终会出现重复,因为
- 为了获取实体/ID,我必须进行一次往返
- 该操作只是简单地添加值,而不首先检查它是否存在
解决方案
只需使用补丁脚本。
using (var session = store.OpenSession())
{
var listing = _session.Query<ListingData>()
.Where(l => l.ListingId == listingId && l.OwnerId == userId)
.ToList().SingleOrDefault();
session.Advanced.Defer(new PatchCommandData(
id: listing.ListingId,
changeVector: null,
patch: new PatchRequest
{
Script = @"
if (this.PhotoUrls.includes(url))
throw ‘Url already exists’;
this.PhotoUrls.push($newUrl);
",
Values =
{
["newUrl"] = "The Url to add"
}
},
patchIfMissing: null));
session.SaveChanges();
}
看:
推荐阅读
- r - 使用 plotROC 绘制多条 roc 曲线(相同颜色)时设置线 alpha
- reactjs - TypeError: this.setState 不是函数,在 Redux Actions 文件中
- codeigniter - Codeigniter:使用查询字符串的分页无法正常工作
- css - 如何从导航菜单的底部边框到横幅图像的末尾水平和垂直居中文本框?
- ruby-on-rails - 什么是每次请求都调用 API 的替代方法
- go - 在自定义范围内生成随机数
- groovy - Jmeter 如果控制器不使用 Groovy 执行
- node.js - 在 mac 中运行(npm install -g @angular/cli)时出错
- hadoop - 错误:hbase:meta 表不一致
- python - 如何使用 Google API 从具有坐标的数据集中获取地址?