Пример 45: управление транзакциями в триггерах, хранимых функциях и процедурах
Решение для Oracle выглядит следующим образом. Да, именно так и выглядит, т.к. в Oracle нет такого явления, как автоподтверждение транзакций — этот эффект может быть реализован некоторыми средствами работы с СУБД, но сама СУБД всегда ждёт явного COMMITT или ROLLBACK.
Oracle |
Решение 6.2.3.b (код функции) |
1CREATE FUNCTION NO AUTOCOMMITT
2RETURN INT
3DETERMINISTIC
4IS
5BEGIN
6DBMS OUTPUT.PUT LINE('Have a nice day :)');
7RETURN 1
8END;
Проверить работоспособность и корректность представленного решения можно выполнением следующего кода.
Oracle Решение 6.2.3.Ь (код для проверки работоспособности решения)
1 SET SERVEROUTPUT ON;
2 SELECT NO AUTOCOMMITT FROM DUAL;
На этом решение данной задачи завершено.
ЧРешение 6.2.3.C 465.
Идея решения данной задачи состоит в том, чтобы использовать такой уровень изолированности транзакций, который меньше всего подвержен влиянию со стороны блокировок, порождённых другими транзакциями.
В MySQL таким уровнем является READ UNCOMMITTED, в MS SQL Server —
тоже READ UNCOMMITTED или SNAPSHOT (но SNAPSHOT может приводить к допол-
нительным расходам ресурсов), в Oracle чтение данных всегда происходит в независимом режиме, потому в этой СУБД можно использовать READ COMMITTED (тем более, что READ UNCOMMITTED в Oracle нет).
Решение для MySQL выглядит следующим образом.
MySQL і |
Решение 6.2.3.C (код процедуры) |
[ |
1DELIMITER $$................. ........................
2CREATE PROCEDURE COUNT_ROWS(IN table_name VARCHAR 150),
3 |
OUT rows_in_table INT) |
4 |
BEGIN |
5 |
SET SESSION TRANSACTION |
6 |
ISOLATION LEVEL READ UNCOMMITTED; |
7 |
|
8 |
SET @count_query = |
9 |
CONCAT('SELECT COUNT(1) INTO @rows_found |
10 |
FROM ' , table_name); |
11 |
|
12PREPARE count_stmt FROM @count_query
13EXECUTE count_stmt;
14DEALLOCATE PREPARE count_stmt
15
16SET rows_in_table := @rows_found
17END;
18$$
19DELIMITER ;
Проверить работоспособность и корректность представленного решения можно выполнением следующего кода.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 500/545
Пример 45: управление транзакциями в триггерах, хранимых функциях и процедурах
Задание 6.2.3.TSK.A: создать на таблице subscriptions триггер, определяющий уровень изолированности транзакции, в котором сейчас проходит операция обновления, и отменяющий операцию, если уровень изолированности транзакции отличен от REPEATABLE READ.
Задание 6.2.3.TSK.B: создать хранимую функцию, порождающую исключительную ситуацию в случае, если выполняются оба условия:
•режим автоподтверждения транзакций выключен;
•функция запущена из вложенной транзакции.
Подсказка: эта задача имеет решение только для MS SQL Server.
Задание 6.2.3.TSK.C: создать хранимую процедуру, выполняющую подсчёт количества записей в указанной таблице таким образом, чтобы она возвращала максимально корректные данные, даже если для достижения этого результата придётся пожертвовать производительностью.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 502/545
Пример 46: формирование и анализ иерархических структур
Рисунок 7.b — Визуальное представление карты сайта
Теперь, когда все данные подготовлены, мы можем переходить к задачам.
Задача 7.1.1.a{476}: создать функцию, возвращающую список идентификаторов всех дочерних вершин заданной вершины (например, идентификаторов всех подстраниц страницы «Читателям»).
Задача 7.1.1.b{482}: написать запрос для показа всего поддерева заданной вершины дерева, включая саму родительскую вершину (например, всех подстраниц страницы «Читателям», включая саму эту страницу).
Задача 7.1.1.c{485}: написать функцию, возвращающую список идентификаторов вершин на пути от заданной вершины к корню дерева (например, идентификаторов всех вершин на пути от страницы «Архивная» к странице
«Главная»).
Ожидаемый результат 7.1.1 .a.
Для вершины с идентификатором 2 (страница «Читателям») функция должна возвратить следующие данные: shildren_of_2
5,6,12,13,14
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 504/545