为什么NServiceBus Saga超时请求使用错误的Saga ID?

时间:2012-01-27 02:37:46

标签: c# nhibernate fluent-nhibernate nservicebus saga

My Saga消息处理程序(配置为ISagaStartedBy)为收到的每条消息请求超时消息。

一次调试几条消息,我发现第一次触发处理程序的时间,发送到超时管理器的传奇ID与a)持久存储在数据库中的传统ID不同,b)传奇后续邮件中发送的ID。后续消息都从数据库中发送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是否已保存在数据库中?或者这是检查真正的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的Id将数据从数据库中拉出来的原因是因为一次只有一个saga活动因此使用PseudoSagaID但它仍然应该以相同的方式工作。如果没有传奇,那么应该创建一个并且应该在那时生成一个新的guid等并且预先设置。但事实并非如此......

0 个答案:

没有答案