Domanda

I'm wondering if anyone has encountered this before:

I handle a command, and in the handler, I save an event to the eventstore (joliver).
Right after dispatching, the handler for the same command is handled again.
I know its the same command because the guid on the command is the same.

After five tries, nservicebus says the command failed due to the maximum retries.
So obviously the command failed, but I don't get any indication of what failed. I've put the contents of the dispatcher in a try catch, but there is no error caught. After the code exits the dispatcher, the event handler will always fire as if something errored out.

Tracing through the code, the events are saved to the database (I see the row), the dispatcher runs, and the Dispatched column is set to true, and then the handler handles the command again, the process repeats, and another row gets inserted into the commits table.

Just what could be failing? Am I not setting a success flag somewhere in the event store? If I decouple the eventstore from nServicebus, both will run as expected with no retries and failures.

The dispatcher:

    public void Dispatch(Commit commit)
    {
        for (var i = 0; i < commit.Events.Count; i++)
        {
            try
            {
                var eventMessage = commit.Events[i];
                var busMessage = (T)eventMessage.Body;
                //bus.Publish(busMessage);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

The Wireup.Init()

    private static IStoreEvents WireupEventStore()
    {
        return Wireup.Init()
            .LogToOutputWindow()
            .UsingSqlPersistence("EventStore")
            .InitializeStorageEngine()
            .UsingBinarySerialization()
            //.UsingJsonSerialization()
            //    .Compress()
            //.UsingAsynchronousDispatchScheduler()
            //    .DispatchTo(new NServiceBusCommitDispatcher<T>())

           .UsingSynchronousDispatchScheduler()
               .DispatchTo(new DelegateMessageDispatcher(DispatchCommit))

            .Build();
    }
È stato utile?

Soluzione

I had a transaction scope opened on the save that I never closed.

    public static void Save(AggregateRoot root)
    {
        // we can call CreateStream(StreamId) if we know there isn't going to be any data.
        // or we can call OpenStream(StreamId, 0, int.MaxValue) to read all commits,
        // if no commits exist then it creates a new stream for us.
        using (var scope = new TransactionScope())
        using (var eventStore = WireupEventStore())
        using (var stream = eventStore.OpenStream(root.Id, 0, int.MaxValue))
        {
            var events = root.GetUncommittedChanges();
            foreach (var e in events)
            {
                stream.Add(new EventMessage { Body = e });
            }

            var guid = Guid.NewGuid();
            stream.CommitChanges(guid);
            root.MarkChangesAsCommitted();

            scope.Complete(); // <-- missing this
        }
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top