Rollback failing when duplicate entry #2456
Replies: 4 comments 1 reply
-
@jay-zahiri I tried to reproduce this today outside of a ASP.Net Core and it behaves exactly as it should. I'm pointing at the Minimal API mechanics. This code: endpoints.MapPost("app/new", async (IDocumentSession documentSession) => {
var @event = new NewEntityAdded(
Guid.NewGuid().ToString(),
"Test"
);
documentSession.Events.StartStream<Entity>(
@event.Id,
@event
);
await documentSession.SaveChangesAsync();
return Results.Created(@event.Id, null);
}); Is very likely pulling the "Scoped" To prove this, either move your code to an MVC controller or inject But at this moment, I do not believe this is a problem in Marten itself. We could do something with documentation here to warn folks about Minimal API. |
Beta Was this translation helpful? Give feedback.
-
Oh, and I'm converting this to a discussion now. |
Beta Was this translation helpful? Give feedback.
-
@jeremydmiller I just tried with ...
endpoints.MapPost("app/new", async (IDocumentStore documentStore) => {
using var documentSession = documentStore.LightweightSession();
... I also tried with controller, getting the same exception. ...
builder.Services
.AddControllers()
.Services
...
app
.UseRouting()
.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
... [ApiController]
[Route("app")]
public class AppController : ControllerBase {
private readonly IDocumentSession _documentSession;
public AppController(IDocumentSession documentSession) {
_documentSession = documentSession;
}
[HttpPost("new")]
public async Task<IActionResult> AddNew(CancellationToken cancellationToken = default) {
var @event = new NewEntityAdded(
Guid.NewGuid().ToString(),
"Test"
);
_documentSession.Events.StartStream<Entity>(
@event.Id,
@event
);
await _documentSession.SaveChangesAsync(cancellationToken);
return Created(@event.Id, null);
}
} Also tried with ...
private readonly IDocumentStore _documentStore;
public AppController(IDocumentStore documentStore) {
_documentStore = documentStore;
}
[HttpPost("new")]
public async Task<IActionResult> AddNew(CancellationToken cancellationToken = default) {
using var documentSession = _documentStore.LightweightSession();
var @event = new NewEntityAdded(
Guid.NewGuid().ToString(),
"Test"
);
documentSession.Events.StartStream<Entity>(
@event.Id,
@event
);
await documentSession.SaveChangesAsync(cancellationToken);
... I'm more worried (I think?) about the console spam. I'm thinking if I upload this and somebody tries to add a duplicate, will it start spamming my log with this? info: Marten.Events.Daemon.AsyncProjectionHostedService[0]
High Water agent is stale at 1
info: Marten.Events.Daemon.AsyncProjectionHostedService[0]
High Water agent is stale after threshold of 3 seconds, skipping gap to events marked after 01/11/2023 18:16:28 +00:00
info: Marten.Events.Daemon.AsyncProjectionHostedService[0]
Daemon projection high water detection skipping a gap in event sequence, determined that the 'safe harbor' sequence is at (null) I'm thinking it does this because of the rollback/tombstone failure? Is it ok that they are failing btw? Should I just ignore that? Thank you for a great library btw! |
Beta Was this translation helpful? Give feedback.
-
I'm seeing the same spamming of console/logs as @jay-zahiri in an ASP.NET Core app when a transaction that includes new events fails. After a cursory look at the Marten source I would agree that this is due to the tombstone failure. And specifically, I think it's because the system is getting fouled because the last attempt to insert into Admittedly this is less likely to show up in systems with normal levels of use. As soon as you get a successful addition of events, the error condition goes away and the log spamming stops. Of course if you have a lot of these failed additions of events intermixed into your normal traffic then this problem will reveal itself in a system with normal use. |
Beta Was this translation helpful? Give feedback.
-
Given the bare-bone setup:
And running it with:
And then calling it twice with:
curl --location --request POST 'https://localhost:5051/app/new'
Gives me the following error
Right after, Marten will start spamming the following in the console:
It is expected that the exception
Npgsql.PostgresException
andMarten.Exceptions.DocumentAlreadyExistsException
is being thrown, but theSystem.ObjectDisposedException
being thrown atMarten.Internal.Sessions.MartenControlledConnectionTransaction.RollbackAsync
andMarten.Internal.Sessions.DocumentSessionBase.tryApplyTombstoneEvents
, coupled with the console spamming of'safe harbor' sequence is at (null)
seems problematic.Is all this expected behaviour? It seems like it's failing to do a rollback and tombstoning an event, and because of that starts spamming the console.
I'm using version 6.0.0-alpha.6 of Marten.
Beta Was this translation helpful? Give feedback.
All reactions