/**
  * @return CarefulDatabaseRunner
  **/
 public function rollback()
 {
     if ($this->running) {
         try {
             $this->transaction->rollback();
         } catch (DatabaseException $e) {
             // keep silence
         }
         $this->running = false;
     }
     return $this;
 }
 public function run()
 {
     Assert::isTrue(!is_null($this->dao) || !is_null($this->db), 'set first dao or db');
     Assert::isNotNull($this->function, 'set first function');
     $transaction = InnerTransaction::begin($this->dao ?: $this->db, $this->level, $this->mode);
     try {
         $result = call_user_func_array($this->function, func_get_args());
         $transaction->commit();
         return $result;
     } catch (\Exception $e) {
         $transaction->rollback();
         if ($this->exceptionFunction) {
             $args = func_get_args();
             array_unshift($args, $e);
             return call_user_func_array($this->exceptionFunction, $args);
         }
         throw $e;
     }
 }