Поиск по сайту:
В английском языке любое слово может быть глаголом. Разве могло бы такое быть в языках программирования? (Алан.Дж.Перлис)

PHP MySQL. Транзакции

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 5,00 из 5)
Загрузка...
20.07.2019
PHP MySQL

Описание : в этой статье вы узнаете, как обрабатывать транзакции MySQL в PHP для обеспечения целостности данных базы данных.

Транзакция представляет собой совокупность взаимозависимых операторов SQL , которые необходимо выполнить во все или ничего режиме. Транзакция успешна, если все операторы SQL выполнены успешно. Сбой любого оператора приведет к откату системы до исходного состояния, чтобы избежать несогласованности данных.

Классическим примером транзакции является транзакция перевода денег с одного банковского счета на другой. Требуется три шага:

  • Проверьте остаток на переведенном счете и посмотрите, достаточна ли сумма для перевода.
  • Если сумма достаточна, вычтите сумму из баланса переведенного счета.
  • Добавьте сумму перевода на баланс получающего счета.

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

 

MySQL транзакция в PHP

Когда вы используете PDO для создания соединения с базой данных , поддерживающей транзакцию, устанавливается режим автоматической фиксации. Это означает, что каждый ваш запрос заключен в неявную транзакцию.

Обратите внимание, что не все механизмы хранения в MySQL поддерживают транзакцию, например, MyISAM не поддерживает транзакцию, однако InnoDB поддерживает.

Для обработки транзакции MySQL в PHP вы используете следующие шаги:

  1. Запустите транзакцию, вызвав метод beginTransaction() объекта PDO.
  2. Поместите операторы SQL и вызов commit() метода в блок try.
  3. Откат транзакции в блоке catch путем вызова метода rollBack() объекта PDO.

 

Пример транзакции PHP MySQL

Мы создадим таблицу с именем accounts, чтобы продемонстрировать перевод денег между двумя банковскими счетами.

Сначала выполните следующую инструкцию для создания таблицы accounts:

CREATE TABLE accounts (
id     INT AUTO_INCREMENT PRITanya KEY,
name   VARCHAR (50)    NOT NULL,
amount DECIMAL (19, 4) NOT NULL
);

 

Во-вторых, вставьте две строки в таблицу accounts:

INSERT INTO accounts(name,amount)
VALUES('AndreyEx',25000),
('Tanya',95000);

В-третьих, запрос к таблице accounts:

SELECT *
FROM accounts;

 

Давайте посмотрим на следующий класс TransactionDemo:

<?php

/**
* PHP MySQL. Демонстрация транзакции
*/
class TransactionDemo {

const DB_HOST = 'localhost';
const DB_NAME = 'classicmodels';
const DB_USER = 'root';
const DB_PASSWORD = '';

/**
* Открыть подключение к базе данных
*/
public function __construct() {
// открыть подключение к базе данных
$conStr = sprintf("mysql:host=%s;dbname=%s", self::DB_HOST, self::DB_NAME);
try {
$this->pdo = new PDO($conStr, self::DB_USER, self::DB_PASSWORD);
} catch (PDOException $e) {
die($e->getMessage());
}
}

/**
* PDO instance
* @var PDO
*/
private $pdo = null;

/**
* Перевод денег между двумя счетами
* @param int $from
* @param int $to
* @param float $amount
* @возвращает true в случае успеха или false в случае неудачи.
*/
public function transfer($from, $to, $amount) {

try {
$this->pdo->beginTransaction();

// получить доступную сумму счета переводчика
$sql = 'SELECT amount FROM accounts WHERE id=:from';
$stmt = $this->pdo->prepare($sql);
$stmt->execute(array(":from" => $from));
$availableAmount = (int) $stmt->fetchColumn();
$stmt->closeCursor();

if ($availableAmount < $amount) {
echo 'Недостаточная сумма для перевода';
return false;
}
// вычесть из передаваемого счет
$sql_update_from = 'UPDATE accounts
SET amount = amount - :amount
WHERE id = :from';
$stmt = $this->pdo->prepare($sql_update_from);
$stmt->execute(array(":from" => $from, ":amount" => $amount));
$stmt->closeCursor();

// добавить в учетную запись получателя
$sql_update_to = 'UPDATE accounts
SET amount = amount + :amount
WHERE id = :to';
$stmt = $this->pdo->prepare($sql_update_to);
$stmt->execute(array(":to" => $to, ":amount" => $amount));

// зафиксировать транзакцию
$this->pdo->commit();

echo 'Сумма успешно переведена';

return true;
} catch (PDOException $e) {
$this->pdo->rollBack();
die($e->getMessage());
}
}

/**
* закройте соединение с базой данных
*/
public function __destruct() {
// close the database connection
$this->pdo = null;
}

}

// тестирование метода передачи
$obj = new TransactionDemo();

// перевод 30000 со счета 1 на счет 2
$obj->transfer(1, 2, 30000);

// перевод 5000 со счета 1 на счет 2
$obj->transfer(1, 2, 5000);

 

Мы открываем соединение с базой данных в методе __construct() и закрываем его в методе __destruct(). В методе transfer():

  • Сначала мы запрашиваем amountпереведенный счет и сравниваем его с суммой перевода, чтобы проверить, достаточен ли остаток на переведенном счете.
  • Во-вторых, если сумма достаточна, мы вычитаем сумму перевода с переведенного счета и добавляем ее на счет получателя.
  • В-третьих, мы фиксируем транзакцию, вызывая метод commit(). Если возникает какая-либо ошибка, мы вызываем метод rollBack() в блоке catch для отката транзакции.

Давайте проверим метод transfer().

// перевод 30K со счета 1 на счет 2

$obj->transfer(1, 2, 30000);

 

Мы перевели 30K со счета AndreyEx на счет Tanya. Мы получили следующее сообщение:

Insufficient amount to transfer

 

Давайте сделаем еще один перевод:

// перевод 5К со счета 1 на счет 2

$obj->transfer(1, 2, 5000);

 

Скрипт возвращает следующее сообщение:

The amount has been transferred successfully.

 

Мы успешно перевели деньги между двумя банковскими счетами.

В этой статье мы шаг за шагом показали, как обрабатывать транзакции MySQL в PHP для обеспечения целостности данных.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Если статья понравилась, то поделитесь ей в социальных сетях:

Читайте также

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

**ссылки nofollow

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Спасибо!

Теперь редакторы в курсе.