Akka.Persistence: SnapshotMetadata
always uses DateTime.MinValue
, which creates "duplicate key" exceptions when multiple snapshots are taken at same seqNr
#7312
Labels
Milestone
Version Information
Version of Akka.NET? v1.5.27.1 and all prior versions
Which Akka.NET Modules? Akka.Persistence has the bug, but it's only the SQL-based implementations that have this problem
Describe the bug
A bug report from an end-user contained the following exception when using Akka.Persistence.Sql:
The real kicker here is the timestamp value -
0001/01/01
. This isDateTime.MinValue
, which is used as the default timestamp on allSnapshotMetadata
instances used by Akka.Persistence's actor base classes:akka.net/src/core/Akka.Persistence/Eventsourced.cs
Lines 219 to 222 in acc8bd3
And that CTOR always uses
DateTime.MinValue
for the snapshot timestamp:akka.net/src/core/Akka.Persistence/SnapshotProtocol.cs
Lines 62 to 72 in acc8bd3
Expected behavior
It is perfectly valid and legal, according to the Akka.Persistence specification, to have multiple snapshots taken at the same
PersistentId
and sameseqNr
so long as they are separated by Timestamp. The combination of these three values is what is supposed to form the "uniqueness constraint" for a snapshot, hence why Timestamps are included in things likeSnapshotSelection
queries.However, there is a secondary bug in the case of SQL-related plugins: the primary keys for Snapshots themselves are also wrong:
I'll file a second issue for that.
Actual behavior
Saving two snapshots at the same
seqNr
fails.Environment
Running on SQL Server, but I'm sure it's the same issue for the other SQL platforms we support as well.
Additional context
This bug has been around for ~10 years, so I'm sure it doesn't happen very often.
If you're impacted by this bug, I recommend the following workaround:
Persist
on a useless data type you don't care about (i.e. an integer)Recover<int>(i => { });
to just discard those values during recoveryPersist
callback function, THEN callSaveSnapshot
- this will force theseqNr
to implement even though you're not actually using it.The text was updated successfully, but these errors were encountered: