Senior
Design task: there is a system for rapid response teams. A signal comes in, and three teams respond to it simultaneously. Only one team needs to be sent. How can this be done at the database transaction level?
sobes.tech AI
Answer from AI
To solve the problem of simultaneous responses from multiple groups with only one being selected at the transaction level in the database, you can use locking mechanisms and unique constraints.
Approach:
- Create a table, for example,
signal_assignments, where information about which group is assigned to a signal is stored. - When a signal is received, each group attempts to insert a record with a unique key on the signal (for example,
signal_idwith a unique index). - The first transaction that successfully inserts the record 'captures' the signal.
- Other transactions attempting to insert will encounter a unique constraint error and should rollback or retry.
SQL example:
CREATE TABLE signal_assignments (
signal_id UUID PRIMARY KEY,
group_id UUID NOT NULL
);
When processing the signal in a transaction:
BEGIN;
INSERT INTO signal_assignments(signal_id, group_id) VALUES (:signal_id, :group_id);
COMMIT;
If the insert fails due to an existing record, it means the signal has already been assigned to another group.
In Go using transactions:
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 {
// Unique constraint error — signal already assigned
return err
}
return tx.Commit()
}
Thus, at the database level, it is guaranteed that only one group will be assigned to a signal, despite concurrent attempts.