Автор: No Dishwashing Studio - Hotown
Источник статьи:Транзакции базы данных и уровни изоляции
Все права принадлежат автору, при перепечатке указывать источник
При использовании баз данных мы часто рассматриваем совокупность операций как независимую единицу, и эта совокупность, составляющая единую логическую единицу работы, называетсядела.
модель сделки
Система базы данных должна поддерживать следующие четыре характеристики транзакций, которые в совокупности называютсяACID, соответствующийатомарность(атомарность),последовательность(Последовательность),изоляция(Изоляция),Упорство(Прочность).
Простая модель сделки
Мы используем T для определения этой модели, и ее SQL примерно выглядит так:
-- 操作1:扣除A账户10元
UPDATE account SET amount = amount - 10 WHERE user_name = 'A'
-- 操作2:增加B账户10元
UPDATE account SET amount = amount + 10 WHERE user_name = 'B'
Простейшая модель перевода T. Пользователь A переводит 10 юаней в бухгалтерскую книгу пользователя B.
Затем мы используем эту транзакционную модель для объяснения четырех характеристик транзакций.
1. Атомарность
Атомарность означает, что набор операций, содержащихся в транзакции, является единственным и неделимым. Более того, в случае сбоя какой-либо операции в транзакции необходимо обеспечить откат базы данных в состояние до выполнения всей транзакции.
В транзакции T есть две операции: одна — вычесть 10 юаней со счета A, а другая — добавить 10 юаней на счет B. Эти две операции неразделимы.
Если рассматривать эти две операции как две независимые транзакции, то примем начальное состояние:
A账户:100元
B账户:100元
мы сейчас внедрилиОперация А, баланс счета становится 90 юаней. Тогда, тогда! Серверная взорвалась из-за какой-то неконтролируемой силы. Тогда окончательный результат станет:
A账户:90元
B账户:100元
А и Б начали бесконечно драться. .
Б: Поторопись и переведи мне деньги!
О: Я переключился! Видите ли, с моего счета уже списали 10 юаней!
B: Я не получил его здесь! Смотрите сами, это все еще 100 долларов!
......
2. Консистенция
Принцип согласованности требует, чтобы выполнение транзакции не изменяло согласованность базы данных. То есть, если база данных непротиворечива до выполнения транзакции, согласованность сохраняется и после выполнения транзакции.
Возьмем транзакцию T в качестве примера: перед выполнением T сумма остатков на счетах A и B составляет 200 юаней, тогда нам нужно убедиться, что после выполнения T сумма остатков на счетах A и B по-прежнему равна 200. юань.
3. Настойчивость
Принцип устойчивости требует, чтобы после успешного выполнения транзакции и ее фиксации в базе данных это обновление было устойчивым. То есть, пока транзакция выполняется успешно, любой системный сбой не может отменить фиксацию этой транзакции.
В этой концепции могут быть небольшие лазейки.Например, если результат транзакции хранится в памяти, то после сбоя машины все данные исчезнут.Нам нужно отправить данные на внешний диск и вести запись обновленной информации, так что база данных в режиме Перезапуск после сбоя может восстановить ее в прежнее состояние. Поскольку эта концепция выходит за рамки нашего обсуждения, она не будет здесь повторяться.
4. Изоляция
Изоляция гарантирует, что состояние системы после одновременного выполнения транзакций эквивалентно состоянию системы после последовательного выполнения этих транзакций в некотором порядке.
Если одновременно выполняется несколько транзакций, даже если мы обеспечиваем атомарность и согласованность транзакций, эти операции не являются строго последовательными при выполнении, а чередуются в какой-то невидимой форме, что может привести к несогласованности в конечном состоянии.
Например, мы записываем предыдущую транзакцию T как транзакцию T1 и подразделяем операции в T1, их фактические операции в системе должны быть примерно такими:
/**
* read(x):从数据库中将x传送到执行read操作的事务的主存缓冲区中
*
* write(x):从执行write的事务的主存缓冲区中将x取出并写回数据库(其实还有一个commit过程,这里先忽略)
*/
read(A);
A := A-10;
write(A);
read(B);
B := B+10;
write(B);
Кроме того, мы определяем еще один T2 для вычисления значения A+B:
read(A);
read(B);
A := A+B;
Как будут выполняться параллельные транзакции? Если нам повезет, он может исполниться полностью в порядке T1, T2, тогда конечное состояние temp, которое мы получим, должно быть 200.
Но если есть ситуация, когда А в Т1 успешно вычитается и переключается в БД, то при выполнении операции по увеличению баланса Б она не вся завершается, но выполнение завершается.B := B+10
Позже начните выполнение T2.Хотя переменная B действительно изменилась, она не была записана в базу данных, поэтому temp, вычисленная в T2, становится 90 + 100 = 190.
Общий процесс будет таким:
-- T1
read(A):
A := A-10;
write(A); --这里A在数据库中的值变成了90
read(B);
B := B+10; --这里B确实发生了改变,但是并未提交至数据库
-- T2
read(A); --A = 90
read(B); --B = 100(不是110)
temp := A+B; --得到190
--T1
write(B) --这里B的修改被提交到数据库
Для обеспечения изоляции существуетСистема управления параллелизмом, для выполнения этой обязанности.
уровень изоляции транзакций
Прежде чем представить уровень изоляции транзакций, давайте сначала представимгрязное чтение,галлюцинации,неповторяемое чтениеКонцепция чего-либо.
Грязные чтения, фантомные чтения, неповторяющиеся чтения
- Грязное чтение. Грязное чтение означает, что транзакция обращается к определенным данным и изменяет их, но перед фиксацией другая транзакция также обращается к тем же данным, а затем вносит изменения. Приблизительная модель такова (здесь используются ранее игнорируемыеcommitоперация, эта операция относится к переходу в состояние фиксации после завершения транзакции):
-- T1
read(A);
A := A+1;
write(A);
--T2
read(A);
A := A+2;
write(A);
commit;
-- T1
commit;
- Неповторяемое чтение: в транзакции одни и те же данные считываются дважды, но до завершения транзакции (после первого чтения, перед вторым чтением) считывается другая транзакция. Одни и те же данные считываются и изменяются, что приводит к несогласованности данные считываются дважды, формируя неповторяемое состояние чтения.
-- 假设初始状态,A=10
-- T1
read(A); -- A = 10;
-- T2
read(A);
A = A+10;
write(A);
commit; -- A = 20;
-- T1
read(A); -- A = 20,与第一次不同
- Фантомные чтения: Фантомные чтения происходят, когда две транзакции не выполняются независимо друг от друга. Следующее демонстрирует эту ситуацию с SQL:
-- T1
UPDATE users SET status = 1;
-- T2
insert users (`status`) values ('0')
Затем пользователь, выполнивший операцию T1, с удивлением обнаружил, что все пользовательские состояния были установлены в 1, почему до сих пор стоит 0? ? ? ? ? ?
Уровень изоляции транзакции
-
Сериализуемый: самый высокий уровень изоляции в SQL, который позволяет избежать грязных чтений, фантомных чтений и неповторяющихся чтений. Стоимость также относительно высока, что сильно повлияет на производительность базы данных.
-
Повторяемое чтение: разрешено чтение только зафиксированных данных, и другие транзакции не должны обновлять данные во время двух чтений элемента данных транзакцией. это состояниеФантомного чтения не избежать.
-
Чтение зафиксировано: разрешено только чтение зафиксированных данных, но повторяющиеся чтения не требуются. Избежать этого состояния можно толькогрязное чтение.
-
Чтение незафиксированных: позволяет читать незафиксированные данные. Это самый низкий уровень изоляции, грязных чтений, фантомных чтений и неповторяющихся чтений избежать нельзя.
Attention: все уровни изоляции не разрешеныгрязное письмо, то есть если элемент данных был записан другой транзакцией, которая еще не зафиксирована или не завершена, другим транзакциям не разрешено записывать в него.