metBD (1084482), страница 23
Текст из файла (страница 23)
Пример использования протокола двухфазной блокировки для устранения проблемы зависимости от нефиксированных результатов.
Таблица 45
Время | Транзакция Т3 | Транзакция Т4 | Поле а1 |
t1 | начало | 100 | |
t2 | блокировка записи а1 | 100 | |
t3 | чтение а1 | 100 | |
t4 | начало | а1=а1+100 | 100 |
t5 | блокировка записи а1 | запись а1 | 200 |
t6 | Ожидание | rollback/unlock(а1) (повторный прогон, откат) | 100 |
t7 | чтение а1 | 100 | |
t8 | а1=а1-100 | 100 | |
t9 | запись а1 | 90 | |
t10 | commit | 90 |
Во избежании возникновения данной ошибки Т4 должна предварительно установить блокировку а1 для записи. После выполнения отката этой транзакции выполненное ею обновление а1 будет отменено и этому элементу данных будет возвращено прежнее значение (100). В момент начала Т3 она тоже потребует блокировку для записи, но ее можно будет выполнить только после снятия блокировки Т4, поэтому Т3 переводится в состояние ожидания.
Пример использования протокола двухфазной блокировки для устранения проблемы несогласованной обработки.
Таблица 46
Время | Транзакция Т5 | Транзакция Т6 | Поле а1 | Поле в1 | Поле с1 | Поле Sum |
t1 | начало | 100 | 50 | 25 | 0 | |
t2 | начало | Sum=0 | 100 | 50 | 25 | 0 |
t3 | блокировка записи а1 | 100 | 50 | 25 | 0 | |
t4 | чтение а1 | блокировка чтения а1 | 100 | 50 | 25 | 0 |
t5 | а1=а1-100 | Ожидание | 100 | 50 | 25 | 0 |
t6 | запись а1 | Ожидание | 90 | 50 | 25 | 0 |
t7 | блокировка записи с1 | О | 90 | 50 | 25 | 0 |
t8 | чтение с1 | Ожидание | 90 | 50 | 25 | 0 |
t9 | с1=с1+10 | Ожидание | 90 | 50 | 25 | 0 |
t10 | запись с1 | Ожидание | 90 | 50 | 35 | 0 |
t11 | commit/unlock(а1, с1) | Ожидание | 90 | 50 | 35 | 0 |
t12 | чтение а1 | 90 | 50 | 35 | 0 | |
t13 | Sum = Sum +а1 | 90 | 50 | 35 | 90 | |
t14 | блокировка чтения в1 | 90 | 50 | 35 | 90 | |
t15 | чтение в1 | 90 | 50 | 35 | 90 | |
t16 | Sum = Sum +в1 | 90 | 50 | 35 | 140 | |
t17 | блокировка чтения с1 | 90 | 50 | 35 | 140 | |
t18 | чтение с1 | 90 | 50 | 35 | 140 | |
t19 | Sum = Sum +с1 | 90 | 50 | 35 | 175 | |
t20 | c | 90 | 50 | 35 | 175 |
Для устранения этой проблемы в Т5 операциям чтения должна предшествовать установка блокировки соответствующих элементов данных для записи, тогда как в Т6 операциям чтения должна предшествовать установка блокировки считываемых элементов данных для чтения.
Можно доказать, что если все транзакции в графике следуют двухфазному протоколу блокировки, этот график гарантированно будет конфликтно упорядоченным.
Каскадный откат
О днако, несмотря на то, что двухфазный протокол гарантирует упорядоченность, могут иметь место проблемы с интерпретацией допустимого момента выполнения отмены блокировок.
Таблица 47
Время | Транзакция Т14 | ТранзакцияТ15 | Транзакция Т16 |
t1 | начало | ||
t2 | блокировка записи а1 | ||
t3 | чтение а1 | ||
t4 | блокировка чтения в1 | ||
t5 | чтение в1 | ||
t6 | а1=в1+а1 | ||
t7 | запись а1 | ||
t8 | снятие блокировки а1 | начало | |
t9 | … | блокировка записи а1 | |
t10 | … | чтение а1 | |
t | … | а1=а1+100 | |
t12 | …. | запись а1 | |
t13 | … | снятие блокировки а1 | |
t14 | … | … | |
t15 | откат | … | |
t16 | … | начало | |
t17 | …. | блокировка чтения а1 | |
t18 | откат | …. | |
t19 | откат |
З десь транзакция Т14 выполняет блокировку счета а1 для записи, после чего суммирует его текущее значение с текущим значением в1, для которого устанавливается блокировка для чтения. Полученное новое значение заносится в БД на счет а1, после чего блокировка а1
отменяется. Затем Т15 устанавливает блокировку а1 для записи, считывает его текущее значение, изменяет и записывает новое значение, после чего отменяет блокировку а1. Наконец, Т16 устанавливает блокировку счета а1 для чтения и считывает его текущее значение. В этот момент происходит отказ в работе Т14, в результате которого происходит ее откат. Однако, поскольку Т15 зависит от результатов Т14, для нее также необходимо выполнить откат. Аналогично - для Т16.
Подобная ситуация, в которой отмена единственной транзакции приводит к целой серии откатов зависящих от нее транзакций, называется каскадным откатом.
Каскадные откаты – явление нежелательное, поскольку потенциально они способны привести к потере большого объема выполненной работы. Очевидно, что было бы очень полезно разработать протокол, исключающий возникновение каскадных откатов.
Одним из возможных вариантов является дополнение обычного двухфазного протокола блокировки требованием откладывать выполнение отмены всех установленных блокировок до конца транзакции – как в предыдущих примерах. В подобном случае продемонстрированная в последнем примере проблема никогда не возникнет, поскольку Т15 не сможет установить требуемую ей блокировку для записи, пока Т14 не завершит свою работу тем или иным образом. Этот вариант протокола называется строгим 2PL. Может быть доказано, что при использовании строгого протокола двухфазной блокировки транзакции могут быть расположены в том порядке, в котором они завершают свою работу.
Другой вариант протокола 2PL, называемый ограниченным 2PL, предусматривает откладывание до конца транзакции освобождение только блокировок для записи. В большинстве СУБД реализуется один из этих двух вариантов протокола 2PL.
Взаимная блокировка