/** * @param \Atrauzzi\PhpEventSourcing\AggregateRoot $aggregateRoot * @throws \Atrauzzi\PhpEventSourcing\Exception\OptimisticConcurrency */ public function save(AggregateRoot $aggregateRoot) { foreach ($aggregateRoot->getUncommittedEvents() as $event) { $this->eventStore->beginTransaction(); $sequenceKey = sprintf('%s%s', $aggregateRoot->getType(), $aggregateRoot->getId()); /** @var \Atrauzzi\PhpEventSourcing\GoogleCloudDatastore\EventSequence|null $sequence */ $sequence = $this->sequenceStore->fetchByName($sequenceKey); if ($sequence) { $currentSequence = $sequence->getValue(); $desiredSequence = $aggregateRoot->getLastSequence() + 1; if ($currentSequence >= $desiredSequence) { throw new OptimisticConcurrencyException($aggregateRoot, $event); } $sequence->setValue($desiredSequence); } else { $sequence = new EventSequence(); $sequence->setValue(0); } $this->sequenceStore->upsert($sequence); $this->eventStore->upsert($this->createGdsEvent($aggregateRoot, $event)); } }