Skip to content

Commit

Permalink
Adjustments to the revisioned concurrency model. Closes GH-3284
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremydmiller committed Jun 29, 2024
1 parent 9e23037 commit 22ffc3a
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 29 deletions.
5 changes: 5 additions & 0 deletions docs/documents/concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ If using the `IRevisioned` interface, or by mapping another property to the vers
version number from the document itself such that `IDocumentSession.Store()` is essentially `IDocumentSession.UpdateVersion(entity, entity.Version)`
:::

::: warning
Marten will not perfectly keep incrementing the IRevisioned.Revision number if the same document is repeatedly stored by the
same session. Prefer using `UpdateRevision()` if you try to continuously update the same document from the same session!
:::

or finally by adding the `[Version]` attribute to a public member on the document type to opt into the
`UseNumericRevisions` behavior on the parent type with the decorated member being tracked as the version number as
shown in this sample:
Expand Down
34 changes: 6 additions & 28 deletions src/DocumentDbTests/Concurrency/numeric_revisioning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,54 +161,32 @@ public async Task store_twice_with_no_version_can_override()
(await theSession.LoadAsync<RevisionedDoc>(doc1.Id)).Name.ShouldBe("Brad");
}

[Fact]
public async Task each_store_should_increase_the_version()
{
var doc1 = new RevisionedDoc { Name = "Tim" };
theSession.Store(doc1);
await theSession.SaveChangesAsync();
doc1.Version.ShouldBe(1);

doc1.Name = "Brad";
theSession.Store(doc1);
await theSession.SaveChangesAsync();
doc1.Version.ShouldBe(2);

doc1.Name = "Janet";
theSession.Store(doc1);

// It's going to warn you to use UpdateRevision here.
var ex = await Should.ThrowAsync<ConcurrencyException>(async () =>
{
await theSession.SaveChangesAsync();
});
}

[Fact]
public async Task optimistic_concurrency_failure_with_update_revision()
{
var doc1 = new RevisionedDoc { Name = "Tim" };
theSession.Store(doc1);
theSession.SaveChanges();
await theSession.SaveChangesAsync();

doc1.Name = "Bill";
theSession.Store(doc1);
theSession.SaveChanges();
await theSession.SaveChangesAsync();

doc1.Name = "Dru";
doc1.Version = 3;
theSession.Store(doc1);
theSession.SaveChanges();
await theSession.SaveChangesAsync();

var doc2 = new RevisionedDoc { Id = doc1.Id, Name = "Wrong" };
theSession.UpdateRevision(doc2, doc1.Version + 1);
theSession.SaveChanges();
await theSession.SaveChangesAsync();

theSession.Logger = new TestOutputMartenLogger(_output);

await Should.ThrowAsync<ConcurrencyException>(async () =>
{
theSession.UpdateRevision(doc2, 2);
theSession.SaveChanges();
await theSession.SaveChangesAsync();
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/Marten/Internal/Operations/StorageOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ protected async Task<bool> postprocessRevisionAsync(DbDataReader reader, IList<E
var revision = await reader.GetFieldValueAsync<int>(0, token).ConfigureAwait(false);
if (Revision > 1) // don't care about zero or 1
{
if (revision >= Revision)
if (revision > Revision)
{
exceptions.Add(new ConcurrencyException(typeof(T), _id));
success = false;
Expand Down

0 comments on commit 22ffc3a

Please sign in to comment.