是什么导致EventStore如此轻松地引发ConcurrencyException? [英] What is causing EventStore to throw ConcurrencyException so easily?

查看:101
本文介绍了是什么导致EventStore如此轻松地引发ConcurrencyException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 JOliver EventStore 3.0,并从简单的示例开始.

Using JOliver EventStore 3.0, and just getting started with simple samples.

我有一个使用NServiceBus的简单pub/sub CQRS实现.客户端在总线上发送命令,域服务器接收并处理命令,然后将事件存储到事件存储中,然后事件存储的调度程序将事件发布到总线上.读取模型服务器然后订阅这些事件以更新读取模型.没什么花哨的,几乎是按书的.

I have a simple pub/sub CQRS implementation using NServiceBus. A client sends commands on the bus, a domain server recieves and processes the commands and stores events to the eventstore, which are then published on the bus by the eventstore's dispatcher. a read-model server then subscribes to those events to update the read-model. Nothing fancy, pretty much by-the-book.

它正在工作,但是只是在简单的测试中,当事件存储到EventStore时,域服务器上(间歇地)出现了许多并发异常.它可以正确地重试,但有时会达到5个重试限制,并且该命令最终会出现在错误队列中.

It is working, but just in simple tests I am getting lots of concurrency exceptions (intermittantly) on the domain server when the event is stored to the EventStore. It properly retries, but sometimes it hits the 5 retry limit and the command ends up on the error queue.

我可以在哪里开始调查导致并发异常的原因?我删除了调度程序,只专注于存储事件,它也有同样的问题.

Where could I start investigating to see what is causing the concurrency exception? I remove the dispatcher and just focus on storing events and it has the same issue.

我正在使用RavenDB来保持EventStore的持久性.我没有做任何花哨的事情,只是这样:

I'm using RavenDB for persistence of my EventStore. I'm not doing anything fancy, just this:

using (var stream = eventStore.OpenStream(entityId, 0, int.MaxValue))
{
  stream.Add(new EventMessage { Body = myEvent });
  stream.CommitChanges(Guid.NewGuid());
}

异常的堆栈跟踪如下:

2012-03-17 18:34:01,166 [Worker.14] WARN NServiceBus.Unicast.UnicastBus [(null)]<(null)>- EmployeeCommandHandler处理消息失败. EventStore.ConcurrencyException:类型的异常 引发了"EventStore.ConcurrencyException".在 EventStore.OptimisticPipelineHook.PreCommit(尝试提交) c:\ Code \ public \ EventStore \ src \ proj \ EventStore.Core \ OptimisticPipelineHook.cs:line 55在EventStore.OptimisticEventStore.Commit(提交尝试)中 c:\ Code \ public \ EventStore \ src \ proj \ EventStore.Core \ OptimisticEventStore.cs:line 90在EventStore.OptimisticEventStream.PersistChanges(Guid commitId) c:\ Code \ public \ EventStore \ src \ proj \ EventStore.Core \ OptimisticEventStream.cs:line 168在EventStore.OptimisticEventStream.CommitChanges(Guid commitId) c:\ Code \ public \ EventStore \ src \ proj \ EventStore.Core \ OptimisticEventStream.cs:line 149在CQRSTest3.Domain.Extensions.StoreEvent(IStoreEvents eventStore,GuidentityId,Object evt) C:\ dev \ test \ CQRSTest3 \ CQRSTest3.Domain \ Extensions.cs:第13行位于 CQRSTest3.Domain.ComandHandlers.EmployeeCommandHandler.Handle(ChangeEmployeeSalary 讯息) C:\ dev \ test \ CQRSTest3 \ CQRSTest3.Domain \ ComandHandlers \ Emplo yeeCommandHandler.cs:第55行

2012-03-17 18:34:01,166 [Worker.14] WARN NServiceBus.Unicast.UnicastBus [(null)] <(null)> - EmployeeCommandHandler failed handling message. EventStore.ConcurrencyException: Exception of type 'EventStore.ConcurrencyException' was thrown. at EventStore.OptimisticPipelineHook.PreCommit(Commit attempt) in c:\Code\public\EventStore\src\proj\EventStore.Core\OptimisticPipelineHook.cs:line 55 at EventStore.OptimisticEventStore.Commit(Commit attempt) in c:\Code\public\EventStore\src\proj\EventStore.Core\OptimisticEventStore.cs:line 90 at EventStore.OptimisticEventStream.PersistChanges(Guid commitId) in c:\Code\public\EventStore\src\proj\EventStore.Core\OptimisticEventStream.cs:line 168 at EventStore.OptimisticEventStream.CommitChanges(Guid commitId) in c:\Code\public\EventStore\src\proj\EventStore.Core\OptimisticEventStream.cs:line 149 at CQRSTest3.Domain.Extensions.StoreEvent(IStoreEvents eventStore, Guid entityId, Object evt) in C:\dev\test\CQRSTest3\CQRSTest3.Domain\Extensions.cs:line 13 at CQRSTest3.Domain.ComandHandlers.EmployeeCommandHandler.Handle(ChangeEmployeeSalary message) in C:\dev\test\CQRSTest3\CQRSTest3.Domain\ComandHandlers\Emplo yeeCommandHandler.cs:line 55

推荐答案

我知道了.不得不仔细研究源代码才能找到它.我希望可以更好地记录下来!这是我新的事件库关联:

I figured it out. Had to dig through source code to find it though. I wish this was better documented! Here's my new eventstore wireup:

EventStore = Wireup.Init()
          .UsingRavenPersistence("RavenDB")
          .ConsistentQueries()
          .InitializeStorageEngine()
          .Build();

我必须添加.ConsistentQueries(),以使raven持久性提供程序在事件存储库正在对raven进行的查询中内部使用WaitForNonStaleResults.

I had to add .ConsistentQueries() in order for the raven persistence provider to internally use WaitForNonStaleResults on the queries eventstore was making to raven.

基本上,当我添加一个新事件,然后在raven赶上索引之前尝试添加另一个事件时,流修订不是最新的.第二个事件将在第一个事件上发生.

Basically when I add a new event, and then try to add another before raven has caught up with indexing, the stream revision was not up to date. The second event would step on the first one.

这篇关于是什么导致EventStore如此轻松地引发ConcurrencyException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆