Транзакция базы данных не откатывается в JModelAdmin — Joomla 3.x

#php #mysql #joomla #transactions

#php #mysql #joomla #транзакции

Вопрос:

Я разрабатываю компонент календаря для Joomla 3.x. Я использую MySQL 5.5.32

В серверной части у меня есть форма для сохранения данных о событиях в базе данных и загрузки изображения.

Чтобы справиться с изображением, я расширяю JModelAdmin и переопределяю функцию сохранения.

 public function save($data)
{ 
  [...]

  $db = $this->getDbo();

  try
  {
    $db->transactionStart();

    // Move uploaded image in correct folder
    if($image = FileUtility::preprocessJFormFile('image', '/images/aftevents/'))
    {
      $fileExtension = JFile::getExt($image);
      // register the image extension to be saved in the database
      $data['image_ext'] = $fileExtension;
    }


    if (parent::save($data))
    {

      // Rename image with event id
      if($image)
      {

        $id = $data['id'] ? $data['id'] : $this->getState($this->getName().'.id', 0);

        if(!$id)
        {
          throw new Exception('COM_AFTEVENTS_EXCEPTION_NO_ID', 1502);
        }

        $finalImage = JPATH_ROOT.'/images/aftevents/'. $id .'.'. $fileExtension;

        JFile::move($image, $finalImage);

        // Create thumbnails
        $params = JComponentHelper::getParams('com_aftevents');
        $params->toArray();
        $IEWidth = $params['image_event_width'];
        $IEHeight = $params['image_event_height'];
        $ICWidth = $params['calendar_image_event_width'];
        $ICHeight = $params['calendar_image_event_height'];

        $jimage = new JImage($finalImage);
        $thumbs = $jimage->createThumbs(array($IEWidth.'x'.$IEHeight, $ICWidth.'x'.$ICHeight), 5);
      }

      $db->transactionCommit();
      return true;
    }

  }
  catch (Exception $e)
  {
      // catch any database errors.
      $db->transactionRollback();

      $this->setError($e->getMessage());
      return false;
  }

  return false;
}
 

Теперь транзакция не работает. Если перехватывается исключение, вставка в базу данных не откатывается.

Я полагаю, это связано с тем, что инструкции по транзакции и вставка базы данных не вызываются одним и тем же объектом JDatabaseDriver или где-то в родительских классах используется другая транзакция, когда запись сохраняется в базе данных, и это портит эту.

Кто-нибудь знает, как заставить мою транзакцию работать?

Комментарии:

1. Итак, ваша идея состоит в том, чтобы обернуть вызываемый родительский save() в транзакцию, а также в try catch? Имейте в виду, что вы не передаете $ db родительскому элементу и что сам родительский элемент не выполняет запрос на обновление, который выполняется в классе JTable. Я бы сказал, что вы могли бы сделать, это в вашем классе table предоставить метод store (), который включает поддержку транзакций.

2. Я понимаю вашу точку зрения. Я собираюсь попробовать это и сообщить вам. Дело в том, что не имеет особого смысла иметь дело с изображением в классе Jtable.

3. Ваша цель не сохранить запись, если загрузка не работает? В этом случае я бы выполнил загрузку перед save() .

4. Мой скрипт заботится о загрузке файла перед вставкой в базу данных. После этого мне нужно переименовать файл с идентификатором события и создать несколько эскизов. Я мог бы сделать это перед обновлением, но для вставки я должен сделать это после, чтобы получить идентификатор, сгенерированный автоинкрементом в базе данных.

5. Хорошо, я сделал то, что хотел, скопировав полную функцию сохранения класса JModelAdmin непосредственно в мой подкласс и адаптировав приведенный выше код. У меня действительно есть доступ к нужному объекту JTable в этой функции. Это немного грязно, но работает.

Ответ №1:

Транзакции могут использоваться только с механизмом хранения, поддерживающим транзакции, таким как InnoDB. Все основные таблицы Joomla используют InnoDB, однако сторонние расширения не могут. Проверьте это перед использованием транзакций.

Измените механизм хранения таблиц на InnoDB.