void IHandle <StorageMessage.WriteCommit> .Handle(StorageMessage.WriteCommit message) { Interlocked.Decrement(ref FlushMessagesInQueue); try { var commitPos = Writer.Checkpoint.ReadNonFlushed(); var result = ReadIndex.CheckCommitStartingAt(message.TransactionPosition, commitPos); switch (result.Decision) { case CommitDecision.Ok: { var commit = WriteCommitWithRetry(LogRecord.Commit(commitPos, message.CorrelationId, message.TransactionPosition, result.CurrentVersion + 1)); ReadIndex.Commit(commit); break; } case CommitDecision.WrongExpectedVersion: message.Envelope.ReplyWith(new StorageMessage.WrongExpectedVersion(message.CorrelationId)); break; case CommitDecision.Deleted: message.Envelope.ReplyWith(new StorageMessage.StreamDeleted(message.CorrelationId)); break; case CommitDecision.Idempotent: message.Envelope.ReplyWith(new StorageMessage.AlreadyCommitted(message.CorrelationId, result.EventStreamId, result.StartEventNumber, result.EndEventNumber)); break; case CommitDecision.CorruptedIdempotency: // in case of corrupted idempotency (part of transaction is ok, other is different) // then we can say that the transaction is not idempotent, so WrongExpectedVersion is ok answer message.Envelope.ReplyWith(new StorageMessage.WrongExpectedVersion(message.CorrelationId)); break; case CommitDecision.InvalidTransaction: message.Envelope.ReplyWith(new StorageMessage.InvalidTransaction(message.CorrelationId)); break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception exc) { Log.ErrorException(exc, "Exception in writer."); throw; } finally { Flush(); } }