public EventAppendResult AppendEventStreams(IEnumerable <IEventStream> eventStreams) { lock (_lockObj) { var eventStreamDict = GroupEventStreamByAggregateRoot(eventStreams); var eventAppendResult = new EventAppendResult(); foreach (var entry in eventStreamDict) { var aggregateRootId = entry.Key; var eventStreamList = entry.Value; //检查当前聚合根的事件是否合法 if (!CheckAggregateEvents(aggregateRootId, eventStreamList, eventAppendResult, out AggregateLatestVersionData aggregateLatestVersionData)) { continue; } //如果合法,则持久化事件到文件 foreach (var eventStream in eventStreamList) { var record = new EventStreamRecord { AggregateRootId = eventStream.AggregateRootId, AggregateRootType = eventStream.AggregateRootType, Version = eventStream.Version, CommandId = eventStream.CommandId, Timestamp = eventStream.Timestamp, CommandCreateTimestamp = eventStream.CommandCreateTimestamp, Events = eventStream.Events }; if (aggregateLatestVersionData != null) { record.PreviousRecordLogPosition = aggregateLatestVersionData.LogPosition; } //写入事件到文件 _eventDataChunkWriter.Write(record); //更新聚合根的内存缓存数据 RefreshMemoryCache(aggregateRootId, ref aggregateLatestVersionData, record); //添加事件到事件队列,以便进行异步持久化事件索引和命令索引 _eventStreamRecordQueue.Enqueue(record); } eventAppendResult.SuccessAggregateRootIdList.Add(aggregateRootId); } return(eventAppendResult); } }
private bool CheckAggregateEvents(string aggregateRootId, IList <IEventStream> eventStreamList, EventAppendResult eventAppendResult, out AggregateLatestVersionData aggregateLatestVersionData) { aggregateLatestVersionData = null; //检查版本号是否连续 if (!IsEventStreamVersionSequential(aggregateRootId, eventStreamList)) { eventAppendResult.DuplicateEventAggregateRootIdList.Add(aggregateRootId); return(false); } //检查命令是否重复 var duplicatedCommandIdList = CheckDuplicatedCommands(eventStreamList); if (duplicatedCommandIdList.Count > 0) { eventAppendResult.DuplicateCommandAggregateRootIdList.Add(aggregateRootId, duplicatedCommandIdList); return(false); } //检查版本号是否是基于当前聚合根最新的版本号而进行的修改 if (!CheckAggregateRootLatestVersionMatch(aggregateRootId, eventStreamList.First().Version, out aggregateLatestVersionData)) { eventAppendResult.DuplicateEventAggregateRootIdList.Add(aggregateRootId); return(false); } return(true); }