Last active
December 12, 2021 20:06
-
-
Save theaspect/c26d7eb641979a3facb20f6c1e1c4ac7 to your computer and use it in GitHub Desktop.
race and deadlock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Atomicity транзакция выполняется либо полностью либо откатывается целиком | |
-- Consistency если база данных находится в консистентном состоянии (все инварианты выполнены), | |
-- то после транзакции база останется в консистентном состоянии | |
-- внутри транзакции консистентность может нарушаться | |
-- Isolation эффекты одних транзакций не должны влиять на другие транзакции | |
-- Durability эффекты от завершенной транзакции должны быть устойчивыми | |
-- Transaction последовательность операций либо выполняется либо отклонояется | |
-- Инварианты: | |
-- Суммарный баланс не должен меняться | |
-- Баланс >= 0 | |
drop table if exists account; | |
create table account(client varchar(100) primary key, balance int); | |
insert into account values | |
('vasya', 100), | |
('petya', 200); | |
select * from account; | |
-- do check in application petya's balance >= 100 | |
-- BEGIN; | |
update account set balance = balance - 100 where client = 'petya'; | |
update account set balance = balance + 100 where client = 'vasya'; | |
-- COMMIT; | |
-- ROLLBACK; | |
select * from account; | |
-- Race Condition (Lost Update) | |
-- Connect1 Connect2 | |
-- read petya read petya | |
-- check petya balance check petya balance | |
-- petya -100 | |
-- write 100 | |
-- petya -200 | |
-- write 0 | |
BEGIN; | |
select * from account; | |
UPDATE account set balance = balance + 10 where client = 'petya'; | |
select * from account; | |
ROLLBACK; | |
-- Одновременно во втором коннекте НАЧАЛО | |
BEGIN; | |
select * from account; | |
UPDATE account set balance = balance + 20 where client = 'petya'; | |
select * from account; | |
COMMIT; | |
-- Одновременно во втором коннекте КОНЕЦ | |
-- Option 1 прервать | |
-- Option 2 перезапустить | |
-- Deadlock | |
select * from account; | |
BEGIN; | |
UPDATE account set balance = balance + 10 where client = 'petya'; | |
select * from account; | |
UPDATE account set balance = balance - 1 where client = 'vasya'; | |
select * from account; | |
COMMIT; | |
-- Одновременно во втором коннекте НАЧАЛО | |
select * from account; | |
BEGIN; | |
UPDATE account set balance = balance - 10 where client = 'vasya'; | |
select * from account; | |
UPDATE account set balance = balance + 1 where client = 'petya'; | |
COMMIT; | |
-- Одновременно во втором коннекте КОНЕЦ | |
-- Lock, Unlock, Read, Write | |
-- p == petya | |
-- v == vasya | |
-- T1 T2 | |
-- lock(p) | |
-- lock(v) | |
-- read(p) | |
-- read(v) | |
-- write(p) | |
-- write(v) | |
-- lock(v) <- Ждём T2 | |
-- lock(p) <- Ждём Т1 | |
-- обнаружена блокировка | |
-- rollback T2: | |
-- unlock(v) | |
-- блокировка v успешна | |
-- read(p) | |
-- write(p) | |
-- commit: | |
-- unlock(v) | |
-- unlock(p) | |
-- Список Блокировок | |
-- T1: p | |
-- T2: v | |
-- Граф ожидания | |
-- T1 <-> T2 (цикл в графе) | |
-- Процесс поиска блокировок периодически строит граф и ищет в нём циклы | |
-- stale/fair |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment