AxonFramework
AxonFramework copied to clipboard
Configurable Locking Scheme in SagaStore
It would be beneficial if the SagaStore could adjust it's locking scheme in regards to retrieving sagas from the database.
Ideally the Builder pattern would provide a toggle to change the query performed to retrieve a Saga instance. Doing so, a Saga instance could be enforce to not be acted upon concurrently by two distinct threads, for example when a Saga it's SagaManager is backed by a SubscribingEventProcessor.
Kick-off for this idea comes from Steven Grimm in this user group issue.
There was one thing I ran into in my 2.x implementation of this that went beyond using SELECT FOR UPDATE. The code needs to make sure it acquires locks in a particular order every time, or it risks deadlocks.
Simple example: host A publishes events of classes X and Y on its local event bus in that order, each of which is handled by a Saga on a SubscribingEventProcessor. At the same time, host B publishes events of classes Y and X. If both hosts naively acquire locks in the order the events arrive, host A will get the lock for the Saga that handles X, host B will get the one for the Saga that handles Y, and neither will be able to get the remaining lock.
This would apply even with locking schemes other than SQL row locks, of course.
In my 2.x implementation I solved it by looking at the Saga's UUID and doing a simple string comparison. If it was trying to load a Saga whose UUID was greater than any already-loaded ones, that was fine. If not, it would commit the UnitOfWork and start a fresh one with a new database transaction. In other words, it could only acquire locks in ascending Saga ID order within a single database transaction.
Removed the milestone for now, as we will not be able to resolve this issue within release 4.6.0. We will adjust this ticket accordingly once we pick it up again.
My initial hunch to support the described behavior from @sgrimm-sg by toggling it through Axon Frameworks (then still very new) Builder solution seemed unfitting after taking a look at the original changes just now.
As it stands, I could take the adjustments made in pull request #346 in it's entirety and place them in the PostgresSagaSqlSchema.
I did make some adjustments to the JavaDoc, but other than that, the intent is kept as is.
By doing so, I feel the discussion and envisioned solution in this thread is resolved sufficiently. As such, I have closed the issue with commit https://github.com/AxonFramework/AxonFramework/commit/d29a46b3c63c64a7999c4e720b1ef459c8ecf7df.