Транзакции в PostgreSQL версии 8.0
Несомненно, транзакции очень хороши, но транзакции в предыдущих версиях PostgreSQL пропагандировали лозунг – “все, или ничего”, останавливая транзакцию, если ошибка произошла в ее пределах. К счастью, новая версия PostgreSQL 8 позволяет взглянуть на это подругому, добавляя “savepoints” (точки сохранения), позволяя откатить назад только часть транзакции и восстановиться от ошибки изящно.
Одна из очень хороших особенностей PostgreSQL – транзакции. Они предотвращают случайную потерю данных или их искажение.
Например, скажем, вы хотите удалить записи в таблице. В PostgreSQL команда выглядит так:
template1=# DELETE FROM foo;
Однако, данная команда удаляет все записи в таблице. Это, вероятно, вовсе не то, чего вы хотите, и, если вы не использовали транзакцию, восстановление из резервной копии будет единственным способом восстановить базу. Используя транзакции, вернуть данные очень просто:
BEGIN;
DELETE FROM foo;
DELETE 50
Параметр BEGIN заставляет базу начать транзакцию. Поскольку, скоро вы понимаете, что забыли включить параметр WHERE, и удалили все столбцы, то вам необходимо будет сделать обратную перемотку и восстановить данные:
BEGIN;
DELETE FROM foo;
DELETE 50
ROLLBACK;
Есть один недостаток в такой реализации транзакций – если внутри транзакции произошла ошибка, вы вынуждены сделать перемотку. Команда перемотки должна будет выполнена в пределах транзакции, до того, как произведены какие-либо команды в пределах соединения. Как только перемотка будет выполнена, вы должны будете повторить действия снова в том виде, который не будет вызывать ошибку. Это правило включает в себя и ошибки пользователей: типа удаления всех отчетов в таблице; синтаксические ошибки: типа попытки выбрать из столбца, который не существует. Например:
BEGIN;
UPDATE foo SET bar = (SELECT count(*) FROM baz));
INSERT INTO foo (column1) SELECT column2 FROM bar;
ОШИБКА: отношение "bar" не существует
CREATE TABLE bar (column1 text, column2 float);
ОШИБКА: текущая транзакция прервана
команды, игнорируемые до конца блока
Из-за ошибки вы будете делать перемотку и вся ваша текущая работа будет потеряна. Этот специфический момент транзакций PostgreSQL особенно раздражает в период отладки и тестирования.
Точки сохранения – путь к спасению.
Новая версия PostgreSQL 8 обращается к этой проблеме с помощью точек сохранения - 'savepoints'. Точки сохранения - это именованные метки, которые разбивают транзакцию на этапы, заставляя базу сохранять данные в рамках каждого этапа. В случае ошибки, мы можем определить этап на котором она возникла, и сделать перемотку только до предыдущей точки сохранения, не теряя при этом работу, которая лежит перед savepoint с ошибкой. Поскольку кажная savepoint имеет свое имя, то и обращаться к ней необходимо по ее имени.
Чтобы инициализировать savepoint, вы должны быть в пределах операционного блока:
template1=# BEGIN;
BEGIN
template1=# INSERT INTO foo(column1,column2,column3) VALUES (1,2,0);
INSERT 17231 1
template1=# INSERT INTO foo(column1,column2,column3) VALUES (1,2,0);
INSERT 17232 1
template1=# INSERT INTO foo(column1,column2,column3) VALUES (1,2,0);
INSERT 17233 1
template1=# SELECT * FROM foo;
column1 | column2 | column3
---------+--------+--------
1 | 2 | 0
1 | 2 | 0
1 | 2 | 0
(3 rows)
template1=# SAVEPOINT main_values_inserted;
SAVEPOINT
template1=# INSERT INTO foo(column1,column2,column3) VALUES (1,2,1/0);
ОШИБКА: деление на ноль
ОШИБКА: деление на ноль
В предыдущей версии PostgreSQL, вы потеряли бы все INSERT данные в предыдущем коде (после возникновения ошибки деления на ноль в последнем утверждении INSERT), но в версии 8 вы можете сделать перемотку до определенного savepoint. Обратите внимание, что код содержит savepoint с именем 'main_values_inserted'. Для обратной перемотки до этой savepoint вы можете написать:
template1=# ROLLBACK TO main_values_inserted;
ROLLBACK
Выполняя перемотку до этой savepoint вы сохраняете все, что было до нее, теряя только работу выполненную после savepoint. После перемотки вы можете продолжить свою работу без полного повтора транзакции:
template1=# INSERT INTO foo(column1,column2,column3) VALUES (5,9,10);
INSERT 17234 1
template1=# INSERT INTO foo(column1,column2,column3) VALUES (5,9,10);
INSERT 17235 1
template1=# INSERT INTO foo(column1,column2,column3) VALUES (5,9,10);
INSERT 17236 1
template1=# INSERT INTO foo(column1,column2,column3) VALUES (5,9,10);
INSERT 17237 1
template1=# SAVEPOINT secondary_values_inserted;
SAVEPOINT
template1=# SELECT * FROM foo;
column1 | column2 | column3
---------+--------+--------
1 | 2 | 0
1 | 2 | 0
1 | 2 | 0
5 | 9 | 10
5 | 9 | 10
5 | 9 | 10
5 | 9 | 10
(7 rows)
template1=# SAVEPOINT all_values_inserted;
SAVEPOINT
template1=# DELETE FROM foo;
DELETE 7
template1=# SELECT * FROM foo;
column1 | column2 | column3
---------+--------+--------
(0 rows)
Ой. Также, как и в первом примере этой статьи, вы фактически хотели удалить только одну строку где 'column = 1'. Но вы можете сделать перемотку ко второй savepoint 'all_values_inserted' в коде выше.
template1=# ROLLBACK TO all_values_inserted;
ROLLBACK
template1=# SELECT * FROM foo;
column1 | column2 | column3
---------+--------+--------
1 | 2 | 0
1 | 2 | 0
1 | 2 | 0
5 | 9 | 10
5 | 9 | 10
5 | 9 | 10
5 | 9 | 10
(7 rows)
Обратите внимание, это восстановило все ваши данные. Теперь вы можете запустить корректные команды для удаления.
template1=# DELETE FROM foo WHERE column1 = 1;
DELETE 3
template1=# SELECT * FROM foo;
column1 | column2 | column3
---------+--------+--------
5 | 9 | 10
5 | 9 | 10
5 | 9 | 10
5 | 9 | 10
(4 rows)
Наконец, вы можете завершить вашу транзакцию. Последняя команда SELECT показывает, что целостность данных после всех этих вставок и обратных перемоток не повреждена.
template1=# COMMIT;
COMMIT
template1=# select * from foo;
column1 | column2 | column3
---------+--------+--------
5 | 9 | 10
5 | 9 | 10
5 | 9 | 10
5 | 9 | 10
(4 rows)
Джошуа Д. Дрейк – Президент Command Prompt, Inc. Компания занимается поддержкой PostgreSQL программированием. Он также соавтор 'Практического PostgreSQL' от издательства O'reilly и Партнеров.
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-04-22 » Комментирование кода и генерация документации в PHP
- 2024-04-22 » SEO в России и на Западе: в чем основные отличия
- 2024-04-22 » SEO для международного масштабирования
- 2024-04-22 » Как использовать XML-карты для продвижения сайта
- 2024-04-22 » Цифровой маркетинг: инструменты для продвижения и рекламы в 2024 году
- 2024-04-22 » Что такое CSS-модули и зачем они нам?
- 2024-04-17 » 23 сервиса для эффективного экспресс-аудита любого сайта
- 2024-04-08 » Яндекс переходит на новую версию Wordstat
- 2024-04-08 » Яндекс интегрировал в свой облачный сервис эмпатичную нейросеть
- 2024-04-08 » Новая версия нейросети Claude превзошла по мощности аналоги Google и OpenAI
- 2024-04-08 » Как пользоваться GPT 4 и Claude бесплатно и без VPN
- 2024-03-13 » Стратегии SEO на 2024 год
- 2024-03-13 » Как использовать анимацию с помощью JavaScript-библиотеки GSAP
- 2024-03-13 » Использование GSAP 3 для веб-анимации
- 2024-03-13 » Cогласование топографической съёмки с эксплуатирующими организациями
- 2024-02-19 » Теряются лиды? Как настроить сквозную аналитику
- 2024-02-17 » Мерч и IT: на что обратить внимание в 2024 году
- 2024-02-16 » Копируем с RSync: основные примеры синхронизации файлов
- 2024-02-15 » Лучшие noCode AI платформы для создания диалоговых ботов
- 2024-02-14 » Факторы ранжирования Google 2024 — исследование Semrush
- 2024-02-12 » Перенос сайта на другой хостинг
- 2024-02-05 » В России сформирован реестр хостинг-провайдеров
- 2024-02-04 » Использование SSH для подключения к удаленному серверу Ubuntu
- 2024-02-03 » Подключаемся к серверу за NAT при помощи туннеля SSH. Простая и понятная инструкция
- 2024-02-02 » Настройка CI/CD для Gitlab-репозитория: схемы и гайд по шагам
- 2024-02-01 » GitLab CI Pipeline. Запуск сценария через SSH на удаленном сервере
- 2024-01-29 » Introduction to GitLab’s CI/CD for Continuous Deployments
- 2024-01-26 » Настройка GitLab CI/CD
- 2024-01-25 » Установка shell gitlab runner
- 2024-01-25 » Установка и регистрация gitlab-runner в docker контейнере
Постановка целей, приближение к ним день за днем и, наконец, их достижение — это и есть ключ к счастью Трейси Брайан - - современный американский профессиональный лектор-преподаватель |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.