/**
  * Performs the insert inside a transaction.
  * Override this one if you want to change how events are stored.
  *
  * @param DomainEventStream $events
  * @throws \yii\db\Exception
  */
 protected function performInsert($events)
 {
     $records = array_map([$this->recordClass, 'wrap'], $events->toArray());
     try {
         $rf = new RevisionFinder($this);
         $table = call_user_func([$this->recordClass, 'tableName']);
         foreach ($records as $record) {
             //trigger events manually because we are inserting in batch
             $record->trigger(ActiveRecord::EVENT_BEFORE_INSERT);
         }
         $columns = array_keys(array_values($records)[0]->getAttributes());
         $this->lockTable();
         //lock after ActiveRecord::EVENT_BEFORE_INSERT
         $rows = array_map(function ($record) use($columns, $rf) {
             $attrs = $record->getAttributes();
             $attrs['revision'] = $rf($record['model_type'], $record['model_id']) + 1;
             return $attrs;
         }, $records);
         $this->db->createCommand()->batchInsert($table, $columns, $rows)->execute();
         foreach ($records as $record) {
             //trigger events manually because we are inserting in batch
             $record->trigger(ActiveRecord::EVENT_AFTER_INSERT);
         }
     } finally {
         $this->unlockTable();
     }
 }
 public function commit()
 {
     $events = DomainEventStream::forAppend($this->owner->getPrimaryKey(false), $this->_eventsToPublish);
     $this->_eventStore->appendEvents($events);
     foreach ($this->_callbacks as $callback) {
         $callback();
     }
     $this->_eventsToPublish = new SplQueue();
     $this->_callbacks = [];
 }