Attempted saga duplication with multiple IAmStartedByMessages


(Scott Wilson) #1

Hi all,

We have some sagas where the first event which would start the saga cannot be predetermined. For instance, the order of the events is not always the same, or some events are optional. So we need any of a number of those events to create the saga, but we can’t say for sure which event will be the one to actually create the saga in every circumstance. Thus, our saga definition has more than one IAmStartedByMessages included.

Because of this, we often see traces of NServiceBus attempting to create the saga on some subsequent event in our logs, which fails due to a unique index violation error (we use both the NHibernate persister and Sql persister and this behavior seems to be the same for both) - so the cause of the error is totally understandable. However, we’d like to cut down the noise in our logs so that when we’re searching for errors this won’t be something we need to filter out.

Is it possible to have NServiceBus check to see if the saga exists first and only create one if it doesn’t exist rather than assuming it needs to create the saga on each one of those events? Perhaps an “IMightBeStartedByMessages”? We get that there may be a slight performance impact doing it this way, but we feel in most of the cases we’ve seen the issue, the impact would be negligible. However, this would cut down on the noise that needs to be routinely ignored by our production support team, so there is some value in having this behave differently than today.

Thanks in advance,
Scott


(Mauro Servienti) #2

Hi Scott,

Saga persisters do perform a check for existence before creating the saga, even if it is marked as IAmStartedBy.... The behavior you’re observing is probably due to parallel processing. There are multiple events, related to the same saga, in the queue, they are picked up by the endpoint in parallel, as expected. No Saga exists, and thus each consumed event will attempt to create one, only one of the will succeed.

Does it sound reasonable?

.m


(Ramon Smits) #3

Depending on the persister you can also choose to use pessimistic locking over optimistic concurrency control, this is especially useful for situations where you have a lot of messages that want to update the same saga instance. Currently the only persister that supports this is NHibernate.

We have an issue open for SQL Persistence to add support for pessimistic locking. If that is valuable for your organisation then please comment on that issue.

I would like to add that if you do not want this behavior from happening is that you limit the maximum concurrency to 1. There are situations where this might be needed when working with non-transactional resources. In general that would not be done in sagas but switching to sequential message processing if you only have a single process that consumes messages would also resolve your issue.

Regards,
Ramon


(Bob Langley) #4

Another suggestion: Configure the logging library to filter these events for this specific Saga automatically.