2

更新: 取得してSystem.Data.SqlClient.SqlExceptionいます。メッセージは次のとおりです。

PRIMARY KEY 制約 'PK_Commits' に違反しています。オブジェクト 'dbo.Commits' に重複するキーを挿入できません。\r\nステートメントは終了しました

EventStore は一意の ID として streamid と commitid を使用しているようです。

イベント ストアを使用して、以下のようにイベントを追加します。

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 の構成は以下の通りです。永続ストアとして Sql Serer 2008 を使用しています。

return Wireup.Init()
    .LogToOutputWindow()
        .UsingSqlPersistence(m_connectionName)
        .WithDialect(new MsSqlDialect())
        .EnlistInAmbientTransaction() // two-phase commit
    .InitializeStorageEngine()
    .UsingJsonSerialization()
        .Compress()
    .UsingSynchronousDispatchScheduler()
        .DispatchTo(new DelegateMessageDispatcher(DispatchCommit))
    .Build();

重複コミット例外が発生する理由は何ですか?

ありがとう

4

1 に答える 1

0

同じ問題があります。私の場合、おそらく、異なるスレッドが異なるイベントを同時に同じ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()));
    }
}

それが役立つことを願っています。

于 2013-06-08T09:17:29.920 に答える