Senior
SELECT FOR UPDATE қолданылатын жағдайдың мысалын келтіріңіз, ол deadlock-қа әкелуі мүмкін.
sobes.tech AI
AI-дан жауап
SELECT FOR UPDATE-пен deadlock екі немесе одан да көп транзакциялар бірдей жолдарға блоктау салуға тырысқанда пайда болуы мүмкін, бірақ әртүрлі тәртіпте.
Мысал:
- Транзакция A
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;орындайды — id=1 жолын блоктайды. - Транзакция B
SELECT * FROM accounts WHERE id = 2 FOR UPDATE;орындайды — id=2 жолын блоктайды. - Транзакция A
SELECT * FROM accounts WHERE id = 2 FOR UPDATE;орындайды — id=2 блокын босатуды күтеді. - Транзакция B
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;орындайды — id=1 блокын босатуды күтеді.
Нәтижесінде екі транзакция бір-бірін күтеді, deadlock пайда болады.
Мұндай жағдайларды болдырмау үшін:
- Жолдарды бірдей тәртіпте блоктау керек.
- Блоктау уақытын азайту керек.
- Deadlock-ты өңдеу немесе тайм-ауттарды қолдану керек.
Go тілінде транзакциялар мен SELECT FOR UPDATE қолдану мысалы:
trx1, _ := db.Begin()
// Транзакция 1 account 1-ді блоктайды
row1 := trx1.QueryRow("SELECT balance FROM accounts WHERE id = 1 FOR UPDATE")
// Басқа горутинада немесе процесте:
trx2, _ := db.Begin()
// Транзакция 2 account 2-ді блоктайды
row2 := trx2.QueryRow("SELECT balance FROM accounts WHERE id = 2 FOR UPDATE")
// Егер trx1 енді account 2-ді, ал trx2 — account 1-ді блоктауға тырысса, deadlock пайда болады
Осылайша, deadlock SELECT FOR UPDATE қолданғанда блоктау айналмалы болғанда пайда болады.