Как работает транзакция MySQL и когда нужно выполнить откат?

#php #mysql #mysqli #pdo #transactions

#php #mysql #mysqli #pdo #транзакции

Вопрос:

интересно, как работает транзакция. Вопрос в том, нужно ли мне выполнять откат, если возникает какая-либо ошибка / исключение, когда исключение будет сгенерировано и никогда не достигнет вызова commit()? Если да, то почему и как? и что именно выполняет откат?

рассмотрим следующий PHP-код (некоторый Java-код выполняет подобные вещи примерно так):

 public function deleteAll():void{
    $stmt = $this->con->prepare(
            'DELETE FROM dd WHERE 1'
        );

    $this->con->begin_transaction();
    if(!$stmt->execute()){
        throw new Exception($stmt->error);
    }
    $this->con->commit();
}

public function insert(array $list):void{
    $stmt = $this->con->prepare(
        'INSERT INTO dd(cc) VALUES(?)'
    );
    $stmt->bind_param('s', $v);

        $this->con->begin_transaction();
    foreach($list as $v){
        if(!$stmt->execute()){
            throw new Exception($stmt->error);
        }
    }
    $this->con->commit();
}
  

Примечание:
$this-> con — это объект подключения mysqli (не использующий PDO, хотя и отличается, но PDO и mysqli будут выполнять аналогичные действия, как указано выше). база данных — MySQL, таблица с использованием движка InnoDB.

Код некоторых пользователей показывает, что они перехватывают исключение и выполняют откат. Но я этого не сделал, поскольку commit() никогда не выполняется, если генерируется исключение. Тогда это позволяет мне задаться вопросом, зачем вообще нужен откат.

Я предполагаю, что если одновременно выполняется несколько запросов, например, следующее:

 public function replaceAllWith(array $list):void{
    $this->con->begin_transaction();
    try{
        //do both previous queries at once
        $this->deleteAll();
        $this->insert($list);

        $this->con->commit();
    }catch(Exception $e){
        //error
        $this->con->rollback();
    }
}
  

но тогда откат все равно невозможен, потому что каждый метод / функция выполняется и фиксируется другим методом и другой транзакцией.
Второй вопрос: Выполняю ли я каждую транзакцию при каждом вызове метода или вызываю транзакцию только в функции ‘boss / parent’, которая только вызывает и координирует функции ‘subordinate / helper’ для выполнения работы?

Не уверен, что задаю правильные вопросы. Транзакция базы данных сбивает с толку, многие онлайн-ресурсы показывают только процедурный процесс (только фиксация или затем немедленный откат, что не имеет никакого значения для обычного прямого запроса) без задействованных концепций OO. Пожалуйста, кто-нибудь из профессионалов проведет вас и даст несколько советов. tq.

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

1. Вы должны фиксировать / откатывать только в одном месте. Обычно это должно быть в управляющем коде, а не в функциях, вызываемых из управляющего кода

2. Вы также должны начинать транзакцию только с управляющего кода.