Sobes.tech
Back to questions
Middle
4

Пришёл сигнал, и сразу 3 группы на него откликнулись одновременно, а нам необходимо послать только 1 группу. Как это сделать на уровне транзакций в базе?

Companies where asked
purweb

Answer from AI

sobes.tech AI

Чтобы гарантировать, что при одновременном отклике нескольких групп на сигнал будет выбрана и отправлена только одна, можно использовать транзакции с блокировкой и проверкой состояния в базе данных.

Например, в транзакции:

  1. Начинается транзакция.
  2. Выполняется запрос с блокировкой строки или записи, отвечающей за обработку сигнала (например, SELECT ... FOR UPDATE).
  3. Проверяется, была ли уже отправлена группа по этому сигналу.
  4. Если нет — выбирается одна из групп и фиксируется факт отправки.
  5. Транзакция коммитится.

Таким образом, даже если несколько процессов одновременно попытаются обработать сигнал, только один из них успешно заблокирует запись и выполнит отправку, остальные увидят, что отправка уже выполнена, и не будут дублировать действие.

Пример на 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()

Это классический подход для обеспечения атомарности и предотвращения гонок при параллельной обработке.