#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. Вы также должны начинать транзакцию только с управляющего кода.