Bug summary (Eventuous + PostgreSQL):
CommandService can return success (Success=true, changes present) while the event is missing from the stream in rare concurrent writes.
Where it happens:
• src/Postgres/src/Eventuous.Postgresql/Scripts/2_AppendEvents.sql
• src/Postgres/src/Eventuous.Postgresql/Scripts/3_CheckStream.sql
Root cause:
- append_events uses ON CONFLICT DO NOTHING when inserting into messages.
On stream-position conflict, rows are silently skipped instead of failing.
- check_stream does not lock the stream row (FOR UPDATE) during expected-version check.
Concurrent writers can both pass validation, then one loses insert race.
- Function still returns (new_version, global_position), so caller sees success.
Observed effect:
• Command result indicates success and change.
• Event is absent from stream.
• Read model may look inconsistent with command outcome.
Steps to reproduce the behavior:
Mutliple programs/threads write into same aggregate
via CommandService
if IsSuccess is true events should be in the store
IsSuccess is true IsChanged is true but load of AggregateState from store has no event in it
Bug summary (Eventuous + PostgreSQL):
CommandService can return success (Success=true, changes present) while the event is missing from the stream in rare concurrent writes.
Where it happens:
• src/Postgres/src/Eventuous.Postgresql/Scripts/2_AppendEvents.sql
• src/Postgres/src/Eventuous.Postgresql/Scripts/3_CheckStream.sql
Root cause:
On stream-position conflict, rows are silently skipped instead of failing.
Concurrent writers can both pass validation, then one loses insert race.
Observed effect:
• Command result indicates success and change.
• Event is absent from stream.
• Read model may look inconsistent with command outcome.
Steps to reproduce the behavior:
Mutliple programs/threads write into same aggregate
via CommandService
if IsSuccess is true events should be in the store
IsSuccess is true IsChanged is true but load of AggregateState from store has no event in it