/**
  * @param StateMachineEvent $event
  * @param StateMachineContext $context
  * @return bool
  * @throws Exception
  * @throws \yii\db\Exception
  */
 public function transition(StateMachineEvent $event, StateMachineContext $context)
 {
     // Let the context know which event triggered the transition
     $context->setEvent($event);
     /** @var yii\db\Transaction|false $txn */
     $txn = $this->useTransactions ? $context->getModel()->getDb()->beginTransaction() : false;
     try {
         // Leaving current state...
         foreach ($event->getState()->getExitCommands() as $command) {
             if (!$command->execute($context)) {
                 $txn && $txn->rollBack();
                 return false;
             }
         }
         // Cleanup old timeouts
         Timeout::cleanUp($context);
         // Entering new state...
         $context->getModel()->{$context->getAttr()} = $event->getTarget();
         foreach ($event->getTargetState()->getEnterCommands() as $command) {
             if (!$command->execute($context)) {
                 $txn && $txn->rollBack();
                 return false;
             }
         }
         // Register the new timeouts
         foreach ($event->getTargetState()->getTimeOuts() as $timeout) {
             $timeout->register($context);
         }
         // Persist the context's model data
         $context->getModel()->save();
         // Update Journal - if applicable
         if ($this->modelJournal) {
             $journal = $this->modelJournal;
             /** @var StateMachineJournal $journal */
             $journal::nu($context, $event);
         }
         $txn && $txn->commit();
         // transition completed successfully
         return true;
     } catch (Exception $e) {
         $txn && $txn->rollBack();
         $context->attachException($e);
         throw $e;
     }
 }