Мой обработчик сообщений 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 и т.д.Но дело не в этом ...