Почему запрос тайм-аута NServiceBus Saga использует неверный идентификатор Saga? - PullRequest
0 голосов
/ 27 января 2012

Мой обработчик сообщений Saga (настроенный как ISagaStartedBy) запрашивает сообщение об истечении времени ожидания для каждого полученного сообщения.

Отладка по нескольким сообщениям за раз, я обнаружил, что в первый раз, когда обработчик запускается, идентификатор саги, отправленный диспетчеру тайм-аута, отличается от того, что а) сохранен в базе данных и б) идентификатор саги, отправленный в последующих сообщениях.Все последующие сообщения отправляют Saga ID из базы данных.

Вот обработчик:

public void Handle(PaymentRequested message)
    {
        int timeoutMinutes = 3;

        try 
        {
            timeoutMinutes = int.Parse(ConfigurationManager.AppSettings["TimeoutMinutes"]);

        }
        catch (Exception ex)
        {
        // log errors
        }


        Data.PseudoSagaID = message.PseudoSagaID;

        var child = new TransactionDetail()
                        { // fields added}

        Data.AddTransactionItem(message.TransactionItem);

        RequestUtcTimeout(DateTime.UtcNow.AddMinutes(timeoutMinutes), "Saga ending");
    }

Я также попытался установить Saga ID в коде, но затем он перезаписывается вбаза данных, когда он сохраняется, когда он выходит из обработчика.У меня есть свой личный персистер, который выглядит следующим образом:

public class MySBASagaPersister : ISagaPersister, IDisposable
{
    public MySBASagaPersister(ISessionFactory sessionFactory)
    {
        SessionFactory = sessionFactory;
        Session = sessionFactory.OpenSession();
    }

    public ISessionFactory SessionFactory { get; set; }
    public ISession Session { get; set; }

    #region ISagaPersister Members
    public void Save(ISagaEntity saga)
    {
        Session.Save(saga);
    }

    public void Update(ISagaEntity saga)
    {
        Session.Merge(saga);
    }

    public void UpdateWithDelete(ISagaEntity saga)
    {
        Session.Merge(saga);
    }

    public T Get<T>(Guid sagaId) where T : ISagaEntity
    {
        return Session.CreateCriteria(typeof(T), "b")
                    .Add(Restrictions.Eq("b.Id", sagaId))
                    .SetFetchMode("b.PaymentRequestedTransactionItems", FetchMode.Eager)
                    .SetCacheable(true)
                    .SetCacheMode(CacheMode.Normal)
                    .UniqueResult<T>();

    }

    public T Get<T>(string property, object value) where T : ISagaEntity
    {
        return Session.CreateCriteria(typeof(T), "b")
                    .Add(Restrictions.Eq("b." + property, value))
                    .SetFetchMode("b.PaymentRequestedTransactionItems", FetchMode.Eager)
                    .UniqueResult<T>();
    }



    public void Complete(ISagaEntity saga)
    {
        Session.Delete(saga);
    }
    #endregion


    #region IDisposable Members
    void IDisposable.Dispose()
    {
        if (Session == null) return;
        if (!Session.IsOpen) return;

        Session.Close();
        Session.Dispose();
    }

    #endregion
}

Как я могу проверить, сохранена ли сага в базе данных?Или это неправильный способ проверки подлинности Saga ID?Или мой запрос на тайм-аут неверен?

ОБНОВЛЕНИЕ:

        public override void ConfigureHowToFindSaga()
    {
    // Map PaymentRequested message type.
    ConfigureMapping<PaymentRequested>(
                                        saga => saga.PseudoSagaID,
                                        message => message.PseudoSagaID);

    // Map PaymentCancelled message type.
    ConfigureMapping<PaymentCancelled>(
                                        saga => saga.PseudoSagaID,
                                        message => message.PseudoSagaID);

    }

Причина, по которой я не вытаскиваю сагу из базы данных с помощью идентификатора на основе guid, заключается в том, что активна только одна сагавремя использования псевдо-SagaID, но все равно должно работать так же.Если саги нет, нужно ее создать, и в этот момент следует сгенерировать новый guid и т.д.Но дело не в этом ...

...