Почему моя транзакция PHP не работает? - PullRequest
4 голосов
/ 12 марта 2012

Я работаю над школьным проектом по созданию CMS для моего сайта портфолио. У меня возникают проблемы с работой функции обновления. Я чувствую, что это как-то связано с тем, как я строю транзакцию PDO. В моей базе данных есть таблица проектов, таблица категорий и ассоциативная таблица content_category. Я могу вставлять свои проекты в эти таблицы просто отлично. То, что я хочу сделать, это вставить в мою таблицу проектов, затем удалить все записи из таблицы content_category и, наконец, вставить записи текущей категории в эту ассоциативную таблицу для завершения транзакции. Я получил свое возвращаемое заявление "Проект обновлен". Но таблицы не обновляются. Любые идеи кто-нибудь?

Вот код:

Это функция в моем классе Project.

public function update(){
    try {
        $conn = getConnection();
        $conn->beginTransaction();
        $sql = "UPDATE project 
                SET project_title = :title, 
                    project_description = :desc, 
                    project_isFeatured = :feat, 
                    project_mainImage = :image
                WHERE project_id = :id";
        $st = $conn->prepare($sql);
        $st->bindValue(":id", $this->id, PDO::PARAM_INT);
        $st->bindValue(":title", $this->title, PDO::PARAM_STR);
        $st->bindValue(":desc", $this->description, PDO::PARAM_STR);
        $st->bindValue(":feat", $this->isFeatured, PDO::PARAM_BOOL);            
        $st->bindValue(":image", $this->mainImage, PDO::PARAM_INT);
        $st->execute(); 

        $sql = "DELETE from content_category
                WHERE content_id = :id";
        $st = $conn->prepare($sql);
        $st->bindValue("id", $this->id, PDO::PARAM_INT);
        $st->execute();

        $sql = "INSERT into content_category (content_id, cat_id)
                VALUES (?,?)";
        $st = $conn->prepare($sql);

        foreach($this->categories as $key=>$value){
            $st->execute(array(intval($projectID), intval($value)));                                        
        }
        $conn->commit();
        $conn = null;
        return "Project updated";                   
    }
    catch(Exception $e) {
        echo $e->getMessage();
        $conn->rollBack();
        return "Error... Unable to update!";
    }
}

Ответы [ 3 ]

5 голосов
/ 12 марта 2012

Ваш движок базы данных для таблиц должен быть INNODB. Если вы используете phpMyAdmin, по умолчанию используется MyISAM. (Я не знаю, приведет ли это к тому, что обновления не пройдут или просто будет проигнорирована строка транзакции. Редактирование: почти наверняка в документации сказано, что она выдаст ошибку и ничего не сделает, если вы начнете транзакцию на myISAM)

4 голосов
/ 12 марта 2012

Чтобы убедиться, что вы не сталкиваетесь с ошибкой PDO, вы должны установить сообщение об ошибке PDO следующим образом:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

В PDO есть функции, такие как prepare(), которые либо возвращают false, либо выдают исключение PDOException в зависимости от установленного режима ошибки. Таким образом, он выдаст исключение, и вы точно будете знать, если у вас возникли проблемы!

Кроме того, если ваша база данных не поддерживает транзакции (например, MyISAM), функция beginTransaction() вернет false. Так что, возможно, добавьте туда чек вроде:

if($conn->beginTransaction()) {
   // Do transaction here
} else {
   echo("Unable to use transactions with this database.");
}

Как ни странно, согласно PHP-документации , вы получите исключение, если ваша база данных не поддерживает транзакции ...

К сожалению, не каждая база данных поддерживает транзакции, поэтому PDO необходимо запускать в так называемом режиме «автоматической фиксации» при первом открытии соединения. Режим автоматической фиксации означает, что каждый выполняемый вами запрос имеет собственную неявную транзакцию, если база данных поддерживает ее, или нет транзакции, если база данных не поддерживает транзакции. Если вам нужна транзакция, вы должны использовать метод PDO :: beginTransaction () для ее инициирования. Если базовый драйвер не поддерживает транзакции, будет выдано исключение PDOException (независимо от ваших настроек обработки ошибок: это всегда серьезная ошибка) .

2 голосов
/ 12 марта 2012

Commit возвращает TRUE в случае успеха или FALSE в случае ошибки.Вы можете проверить это.Также проверьте для errorCode .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...