Sobes.tech
Senior

SELECT FOR UPDATE қолданылатын жағдайдың мысалын келтіріңіз, ол deadlock-қа әкелуі мүмкін.

sobes.tech AI

AI-дан жауап

SELECT FOR UPDATE-пен deadlock екі немесе одан да көп транзакциялар бірдей жолдарға блоктау салуға тырысқанда пайда болуы мүмкін, бірақ әртүрлі тәртіпте.

Мысал:

  1. Транзакция A SELECT * FROM accounts WHERE id = 1 FOR UPDATE; орындайды — id=1 жолын блоктайды.
  2. Транзакция B SELECT * FROM accounts WHERE id = 2 FOR UPDATE; орындайды — id=2 жолын блоктайды.
  3. Транзакция A SELECT * FROM accounts WHERE id = 2 FOR UPDATE; орындайды — id=2 блокын босатуды күтеді.
  4. Транзакция 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 қолданғанда блоктау айналмалы болғанда пайда болады.