Sobes.tech
Middle

Er kwam een signaal binnen, en meteen reageerden er drie groepen tegelijk, maar wij hoeven slechts één groep te sturen. Hoe doe je dat op transactieniveau in de database?

sobes.tech AI

Antwoord van 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()

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