MongoDB 变化事件可以被认为是独一无二的吗?
Can MongoDB Change Events be considered unique?
描述
我正在利用 MongoDb 更改流 (C# MongoDB.Driver v2.12.0) 来跟踪单个集合的更改。
在实验用例中,集合存储有关线程执行的信息。
线程有两个属性:
Status
- 运行,已阻止或已完成
BlockedCount
- 阻塞线程数
在执行期间,线程可以生成子线程并被阻塞,直到所有子线程都未完成。每当子线程完成执行时,它都会通过递减父线程的 BlockedCount
来更新数据库。一旦 BlockedCount
降为 0,父线程应继续执行。
订阅更改流的代码:
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<T>>()
.Match(change => change.OperationType == ChangeStreamOperationType.Insert ||
change.OperationType == ChangeStreamOperationType.Update ||
change.OperationType == ChangeStreamOperationType.Replace)
.AppendStage<ChangeStreamDocument<T>, ChangeStreamDocument<T>, ChangeStreamOutputWrapper<T>>(
"{ $project: { '_id': 1, 'fullDocument': 1, 'ns': 1, 'documentKey': 1 }}");
var options = new ChangeStreamOptions
{
FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
};
using (var cursor = await coll.WatchAsync(pipeline, options, cancellationToken))
{
await cursor.ForEachAsync(async change =>
{
// await some handler routine
}, cancellationToken);
}
问题
我注意到即使更新操作完全相同,更改事件也可能不同。
为了更好地解释这一点,这里有一个例子:
有 1 个父线程和 3 个子线程完成执行,观察到两种不同的行为:
父线程的 3 个不同的更新事件:
- “状态”:“阻塞”,“阻塞计数”:2
- “状态”:“阻塞”,“阻塞计数”:1
- “状态”:“阻塞”,“阻塞计数”:0
父线程有 3 个相同的更新事件:
- “状态”:“阻塞”,“阻塞计数”:0
- “状态”:“阻塞”,“阻塞计数”:0
- “状态”:“阻塞”,“阻塞计数”:0
问题
- 这被认为是正常行为吗?
- 是否有某种配置可以防止这种情况发生,并且只触发 'latest' 更新?
是的,这是预期的行为。文档 (link) 指出:
The fullDocument
document represents the most current majority-committed version of the updated document. The fullDocument
document may vary from the document at the time of the update operation depending on the number of interleaving majority-committed operations that occur between the update operation and the document lookup.
据我所知,没有办法克服或调整这种行为。但是,您 可以 做的是直接阅读 updateDescription
,手动跟踪更改。如果仅设置 BlockedCount
(即不删除并稍后重新添加),它不会很复杂。
描述
我正在利用 MongoDb 更改流 (C# MongoDB.Driver v2.12.0) 来跟踪单个集合的更改。 在实验用例中,集合存储有关线程执行的信息。线程有两个属性:
Status
- 运行,已阻止或已完成BlockedCount
- 阻塞线程数
在执行期间,线程可以生成子线程并被阻塞,直到所有子线程都未完成。每当子线程完成执行时,它都会通过递减父线程的 BlockedCount
来更新数据库。一旦 BlockedCount
降为 0,父线程应继续执行。
订阅更改流的代码:
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<T>>()
.Match(change => change.OperationType == ChangeStreamOperationType.Insert ||
change.OperationType == ChangeStreamOperationType.Update ||
change.OperationType == ChangeStreamOperationType.Replace)
.AppendStage<ChangeStreamDocument<T>, ChangeStreamDocument<T>, ChangeStreamOutputWrapper<T>>(
"{ $project: { '_id': 1, 'fullDocument': 1, 'ns': 1, 'documentKey': 1 }}");
var options = new ChangeStreamOptions
{
FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
};
using (var cursor = await coll.WatchAsync(pipeline, options, cancellationToken))
{
await cursor.ForEachAsync(async change =>
{
// await some handler routine
}, cancellationToken);
}
问题
我注意到即使更新操作完全相同,更改事件也可能不同。 为了更好地解释这一点,这里有一个例子:有 1 个父线程和 3 个子线程完成执行,观察到两种不同的行为:
父线程的 3 个不同的更新事件:
- “状态”:“阻塞”,“阻塞计数”:2
- “状态”:“阻塞”,“阻塞计数”:1
- “状态”:“阻塞”,“阻塞计数”:0
父线程有 3 个相同的更新事件:
- “状态”:“阻塞”,“阻塞计数”:0
- “状态”:“阻塞”,“阻塞计数”:0
- “状态”:“阻塞”,“阻塞计数”:0
问题
- 这被认为是正常行为吗?
- 是否有某种配置可以防止这种情况发生,并且只触发 'latest' 更新?
是的,这是预期的行为。文档 (link) 指出:
The
fullDocument
document represents the most current majority-committed version of the updated document. ThefullDocument
document may vary from the document at the time of the update operation depending on the number of interleaving majority-committed operations that occur between the update operation and the document lookup.
据我所知,没有办法克服或调整这种行为。但是,您 可以 做的是直接阅读 updateDescription
,手动跟踪更改。如果仅设置 BlockedCount
(即不删除并稍后重新添加),它不会很复杂。