Exemple #1
0
    async Task SaveSagaData(RelevantSagaInfo sagaDataToUpdate, bool insert)
    {
        var sagaData     = sagaDataToUpdate.SagaData;
        var sagaDataId   = sagaData.Id;
        var sagaDataType = sagaData.GetType();
        var saga         = sagaDataToUpdate.Saga;

        var saveAttempts = 0;

        while (true)
        {
            try
            {
                saveAttempts++;

                if (insert)
                {
                    await _sagaStorage.Insert(sagaData, sagaDataToUpdate.CorrelationProperties);
                }
                else
                {
                    await _sagaStorage.Update(sagaData, sagaDataToUpdate.CorrelationProperties);
                }

                return;
            }
            catch (ConcurrencyException)
            {
                if (saveAttempts > _options.MaxConflictResolutionAttempts)
                {
                    throw;
                }

                // if we get a concurrencyexception on insert, we would not be able to look up the saga by its ID, we would have to look it up by correlating.... could do that too, but then it would swap the order of saga data instances when resolving the conflict
                if (insert)
                {
                    throw;         //< ^^^ - therefore: disable conflict resolution on insert because: how?
                }
                var userHasOverriddenConflictResolutionMethod = sagaDataToUpdate.Saga.UserHasOverriddenConflictResolutionMethod();

                if (!userHasOverriddenConflictResolutionMethod)
                {
                    throw;
                }

                var freshSagaData = await _sagaStorage.Find(sagaDataType, "Id", sagaDataId);

                if (freshSagaData == null)
                {
                    throw new RebusApplicationException($"Could not find {sagaDataType} saga data with ID {sagaDataId} when attempting to invoke conflict resolution - it must have been deleted");
                }

                _log.Debug("Invoking conflict resolution attempt {resolutionAttemps} for saga with ID {sagaDataId}", saveAttempts, sagaDataId);

                await saga.InvokeConflictResolution(freshSagaData);

                sagaData.Revision = freshSagaData.Revision;
            }
        }
    }
Exemple #2
0
        async Task SaveSagaData(RelevantSagaInfo sagaDataToUpdate, bool insert)
        {
            var sagaData = sagaDataToUpdate.SagaData;
            var saga = sagaDataToUpdate.Saga;

            var saveAttempts = 0;

            while (true)
            {
                try
                {
                    saveAttempts++;

                    if (insert)
                    {
                        await _sagaStorage.Insert(sagaData, sagaDataToUpdate.CorrelationProperties);
                    }
                    else
                    {
                        await _sagaStorage.Update(sagaData, sagaDataToUpdate.CorrelationProperties);
                    }

                    return;
                }
                catch (ConcurrencyException)
                {
                    if (saveAttempts > 10) throw;

                    // if we get a concurrencyexception on insert, we would not be able to look up the saga by its ID, we would have to look it up by correlating.... could do that too, but then it would swap the order of saga data instances when resolving the conflict
                    if (insert) throw; //< ^^^ - therefore: disable conflict resolution on insert because: how?

                    var userHasOverriddenConflictResolutionMethod = sagaDataToUpdate.Saga.UserHasOverriddenConflictResolutionMethod();

                    if (!userHasOverriddenConflictResolutionMethod)
                    {
                        throw;
                    }

                    var freshSagaData = await _sagaStorage.Find(sagaData.GetType(), "Id", sagaData.Id);

                    if (freshSagaData == null)
                    {
                        throw new ApplicationException($"Could not find saga data with ID {sagaData.Id} when attempting to invoke conflict resolution - it must have been deleted");
                    }

                    await saga.InvokeConflictResolution(freshSagaData);

                    sagaData.Revision = freshSagaData.Revision;
                }
            }
        }