joliver/EventStore — Issue #89: InvalidOperationException on Commit of retried Undispatched Commit
Author: aduggleby
Created: 2011-11-14 15:35:15+00:00
State: open

When an undispatched event is re-dispatched when the EventStore loads (BuildEventStore) and the retry succeeds EventStore does not mark the commit as dispatched but swallows an InvalidOperationException: "There is already an open DataReader associated with this Command which must be closed first."

Reproducible with .NET4 Console App, EventStore (3.0.11305.44) and EventStore.Serialization.Json (3.0.11305.44) from NuGet using the following code (provide valid connection string and run with empty database):

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EventStore.Dispatcher;
using EventStore;

namespace ESTest
{
class Program : IDispatchCommits
{
static void Main(string[] args)
{
new Program().Run();
}

public Program() { }

public IStoreEvents BuildES()
{
return Wireup.Init()
.UsingSqlPersistence("DB")
.InitializeStorageEngine()
.UsingJsonSerialization()
.UsingSynchronousDispatchScheduler(this)
.Build();
}

public void Run()
{
var guid = Guid.NewGuid();

//
// Step A: Create a failed commit
//

Event.Fail = true;

using (var eventStore = BuildES())
{
var _s = eventStore.OpenStream(guid, 0, Int32.MaxValue);

_s.Add(new EventMessage()
{
Body = new Event()
});
try
{
_s.CommitChanges(Guid.NewGuid());
}
catch { }
}

//
// Step B: the undispatched commit is re-dispatched in BuildEventStore
// and this time all goes well but the commit fails
//

Event.Fail = false;

// This will throw an InvalidOperationException:
// There is already an open DataReader associated with this Command which must be closed first.
// TURN ON "Break on Exceptions: thrown" (otherwise Event Store will swallow the exception)
using (var eventStore = BuildES())
{
// Exception
}
}

public void Dispatch(EventStore.Commit commit)
{
foreach (var @e in commit.Events)
{
(@e.Body as Event).Do();
}
}

public void Dispose()
{

}

public class Event
{
public static bool Fail = true;

public void Do()
{
if (Event.Fail)
{
throw new Exception("Failing");
}
}
}
}
}
```