C# EventStore重复提交异常
更新: 我们得到了C# EventStore重复提交异常,c#,.net,cqrs,C#,.net,Cqrs,更新: 我们得到了System.Data.SqlClient.SqlException。信息是: 违反主键约束“PK_提交”。无法在对象“dbo.Commits”中插入重复键。\r\n语句已终止 似乎EventStore正在使用streamid和commitid作为唯一id 我们使用事件存储来附加事件,如下所示 public bool TryAppend(object[] content) { if (content == null) throw new Argument
System.Data.SqlClient.SqlException
。信息是:
违反主键约束“PK_提交”。无法在对象“dbo.Commits”中插入重复键。\r\n语句已终止
似乎EventStore正在使用streamid和commitid作为唯一id
我们使用事件存储来附加事件,如下所示
public bool TryAppend(object[] content)
{
if (content == null)
throw new ArgumentNullException("content");
try
{
using (var stream = m_storage.OpenStream(m_streamID, 0, int.MaxValue))
{
var versionInStore = stream.StreamRevision;
content.ToList().ForEach(m =>
{
var version = ++versionInStore;
var key = string.Format("{0}-{1:00000000}", m.GetType().Name, version);
var savedMessage = new SavedRecord(key, version, m);
stream.Add(new EventMessage { Body = savedMessage });
});
stream.CommitChanges(Guid.NewGuid());
}
return true;
}
catch (Exception e)
{
m_logger.LogError(e);
return false;
}
}
EventStore的配置如下所示。我们使用SQLSerer2008作为持久性存储
return Wireup.Init()
.LogToOutputWindow()
.UsingSqlPersistence(m_connectionName)
.WithDialect(new MsSqlDialect())
.EnlistInAmbientTransaction() // two-phase commit
.InitializeStorageEngine()
.UsingJsonSerialization()
.Compress()
.UsingSynchronousDispatchScheduler()
.DispatchTo(new DelegateMessageDispatcher(DispatchCommit))
.Build();
你知道为什么会出现dupplicate提交异常吗
谢谢我收到了同样的问题;在我的例子中,这可能是因为不同的线程在同一时间向具有相同id的流添加不同的事件。 已写入以下代码,以便能够重试添加事件:
private void TryAddEvent(IStoreEvents storeEvents, IUserEvent anEvent, Guid streamId)
{
var isCommitSuccessful = false;
for (var i = 0; i < 10 && !isCommitSuccessful; i++)
{
try
{
using (var stream = storeEvents.OpenStream(streamId, 0, int.MaxValue))
{
stream.Add(new EventMessage {Body = anEvent});
if (stream.UncommittedEvents.All(e => e.Body != anEvent))
{
stream.Add(new EventMessage {Body = anEvent});
}
stream.CommitChanges(Guid.NewGuid());
}
isCommitSuccessful = true;
}
catch (Exception ex)
{
if (!(ex is SqlException) && !(ex is ConcurrencyException))
{
throw;
}
using (var stream = storeEvents.OpenStream(streamId, 0, int.MaxValue))
{
if (stream.CommittedEvents.Any(e => e.Body == anEvent))
{
isCommitSuccessful = true;
}
}
}
}
if (!isCommitSuccessful)
{
throw new ConcurrencyException(String.Format("Cannot add {0} to event store", anEvent.GetType()));
}
}
private void TryAddEvent(IStoreEvents storeEvents、IUserEvent anEvent、Guid streamId)
{
var isCommitSuccessful=false;
for(var i=0;i<10&&!isCommitSuccessful;i++)
{
尝试
{
使用(var stream=storeEvents.OpenStream(streamId,0,int.MaxValue))
{
Add(新事件消息{Body=anEvent});
if(stream.UncommittedEvents.All(e=>e.Body!=anEvent))
{
Add(新事件消息{Body=anEvent});
}
stream.CommitChanges(Guid.NewGuid());
}
isCommitSuccessful=真;
}
捕获(例外情况除外)
{
if(!(ex是SqlException)和&!(ex是ConcurrencyException))
{
投掷;
}
使用(var stream=storeEvents.OpenStream(streamId,0,int.MaxValue))
{
if(stream.CommittedEvents.Any(e=>e.Body==anEvent))
{
isCommitSuccessful=真;
}
}
}
}
如果(!isCommitSuccessful)
{
抛出新的ConcurrencyException(String.Format(“无法将{0}添加到事件存储区”,anEvent.GetType());
}
}
希望能有所帮助。谢谢你,尤里,我试试这个。为了解决这个问题,我转向了一个更简单的解决方案。我删除了EventStore库,并通过二进制序列化将消息存储到SQLServer表中。它非常类似于Lokad CQRS事件存储。