Назад к вопросам
Middle
3
Пришёл сигнал, и сразу 3 группы на него откликнулись одновременно, а нам необходимо послать только 1 группу. Как это сделать на уровне транзакций в базе?
Компании, где спрашивали
purweb
Ответ от нейросети
sobes.tech AI
Чтобы гарантировать, что при одновременном отклике нескольких групп на сигнал будет выбрана и отправлена только одна, можно использовать транзакции с блокировкой и проверкой состояния в базе данных.
Например, в транзакции:
- Начинается транзакция.
- Выполняется запрос с блокировкой строки или записи, отвечающей за обработку сигнала (например,
SELECT ... FOR UPDATE). - Проверяется, была ли уже отправлена группа по этому сигналу.
- Если нет — выбирается одна из групп и фиксируется факт отправки.
- Транзакция коммитится.
Таким образом, даже если несколько процессов одновременно попытаются обработать сигнал, только один из них успешно заблокирует запись и выполнит отправку, остальные увидят, что отправка уже выполнена, и не будут дублировать действие.
Пример на Go с использованием базы PostgreSQL и пакета database/sql:
// tx, err := db.Begin()
// defer tx.Rollback()
// row := tx.QueryRow("SELECT sent FROM signals WHERE id = $1 FOR UPDATE", signalID)
// var sent bool
// err = row.Scan(&sent)
// if err != nil {
// return err
// }
// if !sent {
// // Отправляем группу
// _, err = tx.Exec("UPDATE signals SET sent = true WHERE id = $1", signalID)
// if err != nil {
// return err
// }
// }
// return tx.Commit()
Это классический подход для обеспечения атомарности и предотвращения гонок при параллельной обработке.