Загрузка данных
Лабораторная работа «Транзакции»
1. Теоретическая часть.
Транзакция – это неделимая последовательность операций с базой
данных, которая либо выполняется полностью, либо не выполняется
вовсе. Транзакция гарантирует целостность данных.
По умолчанию в MariaDB каждая команда SQL выполняется как
отдельная транзакция (режим autocommit включён). Для работы с
составными транзакциями используют:
Команда Описание
START
TRANSACTION или BEGIN
Начинает новую транзакцию
COMMIT
Фиксирует все изменения текущей
транзакции
ROLLBACK
Отменяет все изменения текущей
транзакции
SAVEPOINT имя Устанавливает точку сохранения
ROLLBACK TO SAVEPOINT
имя
Откатывает изменения до точки
сохранения
RELEASE SAVEPOINT имя Удаляет точку сохранения
2. Практическая часть.
1) Простые транзакции
Отключите автоматическая коммит (для текущей сессии)
SET AUTOCOMMIT = 0;
Создайте транзакцию, изменяющую баланс Иванова и Петрова:
START TRANSACTION;
UPDATE accounts SET balance = balance - 200 WHERE owner = 'Иванов';
UPDATE accounts SET balance = balance + 200 WHERE owner = 'Петров';
SELECT * FROM accounts;
Поскольку в конце запроса не был указан COMMIT в таблицах ничего не
изменилось, теперь попробуем указать тот же запрос, но добавив в
конце COMMIT;
START TRANSACTION;
UPDATE accounts SET balance = balance - 200 WHERE owner = 'Иванов';
UPDATE accounts SET balance = balance + 200 WHERE owner = 'Петров';
SELECT * FROM accounts;
COMMIT;
2) Откат транзакции: ROLLBACK
Введите транзакцию из предыдущего задания, добавив ROLLBACK:
START TRANSACTION;
UPDATE accounts SET balance = balance - 200 WHERE owner = 'Иванов';
UPDATE accounts SET balance = balance + 200 WHERE owner = 'Петров';
SELECT * FROM accounts;
ROLLBACK;
SELECT * FROM accounts;
COMMIT;
1 Задание:
Создайте транзакцию, которая снимает со счёта Иванова сумму,
превышающую его баланс. Напишите запрос, который проверяет баланс
перед списанием и откатывает транзакцию при недостатке средств
(можно использовать переменные или хранимую процедуру).
2) Использование SAVEPOINT.
Установка и откат к точке сохранения:
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE owner = 'Иванов';
SAVEPOINT checkpoint1;
UPDATE accounts SET balance = balance - 200 WHERE owner = 'Иванов';
ROLLBACK TO SAVEPOINT after_first_update;
COMMIT;
Проверьте баланс, он должен соответствовать состоянию после первого
обновления.
Задание 2.
В одной транзакции выполните несколько обновлений, установите
несколько точек сохранения и выполните откат к одной из
промежуточных точек. Зафиксируйте транзакцию. Проследите за
изменением данных.
база данных:
-- phpMyAdmin SQL Dump
-- version 5.2.3-1.red80
-- https://www.phpmyadmin.net/
--
-- Хост: localhost
-- Время создания: Мар 31 2026 г., 04:56
-- Версия сервера: 10.11.15-MariaDB
-- Версия PHP: 8.1.32
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- База данных: `transcation example`
--
-- --------------------------------------------------------
--
-- Структура таблицы `accounts`
--
CREATE TABLE `accounts` (
`id` int(11) NOT NULL,
`owner` varchar(50) NOT NULL,
`balance` decimal(10,2) NOT NULL CHECK (`balance` >= 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
--
-- Дамп данных таблицы `accounts`
--
INSERT INTO `accounts` (`id`, `owner`, `balance`) VALUES
(1, 'Иванов', 1000.00),
(2, 'Петров', 500.00),
(3, 'Сидоров', 200.00);
--
-- Индексы сохранённых таблиц
--
--
-- Индексы таблицы `accounts`
--
ALTER TABLE `accounts`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT для сохранённых таблиц
--
--
-- AUTO_INCREMENT для таблицы `accounts`
--
ALTER TABLE `accounts`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;