Senior
Sarcină de proiectare: există un sistem pentru grupuri de răspuns rapid. Când se primește un semnal, trei grupuri răspund simultan. Este nevoie să se trimită doar un singur grup. Cum se face acest lucru la nivelul tranzacțiilor în baza de date?
sobes.tech AI
Răspuns de la AI
Для решения задачи с одновременным откликом нескольких групп и выбором только одной на уровне транзакций в базе данных можно использовать механизм блокировок и уникальных ограничений.
Подход:
- Создайте таблицу, например,
signal_assignments, где хранится информация о том, какая группа назначена на сигнал. - При получении сигнала каждая группа пытается вставить запись с уникальным ключом по сигналу (например,
signal_idс уникальным индексом). - Первая транзакция, которая успешно вставит запись, «захватывает» сигнал.
- Остальные транзакции при попытке вставки получат ошибку уникального ограничения и должны откатиться или повторить попытку.
Пример на SQL:
CREATE TABLE signal_assignments (
signal_id UUID PRIMARY KEY,
group_id UUID NOT NULL
);
При обработке сигнала в транзакции:
BEGIN;
INSERT INTO signal_assignments(signal_id, group_id) VALUES (:signal_id, :group_id);
COMMIT;
Если вставка не удалась из-за уже существующей записи, значит сигнал уже назначен другой группе.
В Go с использованием транзакций:
func assignGroup(db *sql.DB, signalID, groupID string) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
_, err = tx.Exec(`INSERT INTO signal_assignments(signal_id, group_id) VALUES ($1, $2)`, signalID, groupID)
if err != nil {
// Ошибка уникального ограничения — сигнал уже назначен
return err
}
return tx.Commit()
}
Таким образом, на уровне базы данных гарантируется, что только одна группа будет назначена на сигнал, несмотря на одновременные попытки.