Repository navigation
Release v22.39.0
Added
[ProtectedDecision]commands read the read models their decision depends on through Chronicle decision reads (DecisionRead<T>/IDecisionReads) inside the command's transaction. If another command changes what the decision read before this one commits, the commit is rejected as a concurrency violation (a validation result, HTTP 400) instead of overwriting it (#2828)[Unprotected],CommandDecisionMode, command dependency safety checks, decision scenario helpers forCommandScenario(UseDecisionReads,AppendConcurrently), and the ARCCHR0011/ARCCHR0012 analyzers that point out decisions made outside protection (part of #2828)
Changed
- Chronicle packages are updated from 19.13.0 to 19.23.0 and Fundamentals to 7.19.6 (part of #2828)
- Arc claims ownership of each command's Chronicle unit of work and commits it as owner. A failed command whose unit has enrolled decision reads is rolled back as owner (
RollbackAsOwner); a failed command without decision reads, including every unmarked command, is rolled back through the publicRollback()exactly as before. A direct SDKRollback()orCommit()(including an aggregate root commit) of a protected unit is refused withProtectedUnitOfWorkRequiresOwner(part of #2828) AddReadModelsregisters Arc's command-awareIDecisionReadsandDecisionRead<T>for every read model. In unmarked commandsIDecisionReads.GetDetached<T>andAdmit<T>behave exactly as Chronicle's reader;IDecisionReads.Get<T>andDecisionRead<T>are refused with a message pointing to[ProtectedDecision](on 19.13 an enrolled read in an unmarked command already failed at commit) (part of #2828)
Protection is opt-in: unmarked commands keep their current behavior. A [ProtectedDecision] command refuses discoverable validators rather than supporting them (tracked in #2831); queries it performs still run their own validators, such as paging.
Behavior changes from Chronicle 19.13 to 19.23
These come with the package update and reach applications without code changes:
- Unique constraints honour
IgnoreCasing. The .NET client now sendsIgnoreCasingwhen it registers a unique constraint. Before, the kernel stored every unique constraint as case-sensitive, so a constraint markedIgnoreCasingnow rejects a value that differs only in casing (Cratis/Chronicle#4368, 19.22.0) - Constraint indexes are rebuilt at registration when a constraint's sequences change. A constraint can declare the event sequences it applies to (
ForEventSequences(...),ForEventLog(),EventSequenceson[Unique]). For each newly covered sequence the kernel rebuilds the index from existing events; a sequence no longer covered stops validating. See the known limits in Cratis/Chronicle#4408 (Cratis/Chronicle#4398, 19.23.0) - The ASP.NET Core event store falls back to the client options.
UseCratisChroniclenow uses the client's configured event store unless a web-specific one is set (Cratis/Chronicle#4338) - Logging levels changed. A reactor that loses its kernel connection (gRPC
Unavailable) logs a Warning and reconnects instead of an Error; a cancelled stream logs at Debug (Cratis/Chronicle#4373, 19.22.0). The observer transition trace log category is nowStateMachine<ObserverState>(Cratis/Chronicle#4289) - Unit-of-work lifecycle.
ChronicleOptions.UnitOfWorkLifecyclePolicyis added withCompatibilityas the default, andDispose()during an in-flight commit no longer rolls back or throws (Cratis/Chronicle#4258)