Sobes.tech
Middle+

There is a customer support process. Within it, there is a process of assigning support tickets to an operator. An operator can have no more than 5 tickets at the same time.

sobes.tech AI

Answer from AI

The current implementation has a race condition risk when assigning tickets to operators in parallel, especially if multiple threads try to assign tickets simultaneously. This can lead to exceeding the limit of 5 tickets per operator.

To avoid this, you can:

  1. Use database-level locking — for example, SELECT ... FOR UPDATE when selecting operators with ticket counts.
  2. Implement a database-level constraint, such as a trigger or a CHECK constraint, to prevent more than 5 active tickets per operator.
  3. Add an additional field to the OperatorsTicket table to track the ticket status (active/closed), and consider only active tickets.

An improved approach using transactions and locking:

public void TryAssignOperatorToTicket(int ticketId)
{
    using var transaction = _db.BeginTransaction();

    // Lock operators with fewer than 5 tickets
    var availableOperators = _db.Query<Operator>(@"
        SELECT o.Id, COUNT(ot.TicketId) as TicketsCount
        FROM Operators o
        LEFT JOIN OperatorsTicket ot ON o.Id = ot.OperatorId
        GROUP BY o.Id
        HAVING COUNT(ot.TicketId) < 5
        ORDER BY TicketsCount
        FOR UPDATE
    ");

    var availableOperator = availableOperators.FirstOrDefault();

    if (availableOperator != null)
        _db.AssignTicketToOperator(ticketId, availableOperator.Id);
    else
        _db.AssignTicketToOperator(ticketId, null);

    transaction.Commit();
}

This approach ensures that at the moment of selecting operators, they are locked for other transactions, preventing exceeding the limit.

There is a customer support process. Within it, there… - sobes.tech