Senior
Entwurfsaufgabe: Es gibt ein System für Schnellreaktionsteams. Bei einem Signal reagieren sofort drei Teams gleichzeitig. Es ist nur ein Team zu senden. Wie kann man das auf Transaktionsebene in der Datenbank machen?
sobes.tech KI
Antwort von 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()
}
Таким образом, на уровне базы данных гарантируется, что только одна группа будет назначена на сигнал, несмотря на одновременные попытки.