Question

I am trying to figure out the way to enforce a maximum number of relations in a highly concurrent system. The following is an example use case.

// Job table
job_id   | ... | num_positions
xx-xx-xx | ... | 3

// Positions table - only 1 spot left
position_id | job_id   | user_id
aa-aa-aa    | xx-xx-xx | ee-ee-ee
bb-bb-bb    | xx-xx-xx | ff-ff-ff

Now let's say two people try to fill the last spot at the same time. What is the best/right way to enforce that there will only ever be a maximum of 3 records? Ideally, the transaction that fires first fills the spot. What is the best way to implement this sort of functionality? Isolation levels etc?

Thanks in advance

Was it helpful?

Solution

Think about

// Positions table - 3 spots for `xx-xx-xx` job, only 1 spot is free
position_id | job_id   | user_id
------------+----------+---------
aa-aa-aa    | xx-xx-xx | ee-ee-ee    -- used spot
bb-bb-bb    | xx-xx-xx | ff-ff-ff    -- used spot
cc-cc-cc    | xx-xx-xx | NULL        -- free spot

The amount of spot rows per a job is equal to jobs.num_positions for according job_id value. They're created with according amount when the row is inserted into jobs table or when jobs table is updated and amount value for some job(s) is increased.

While user filling a spot users's id inserts to the user_id column. When user frees a spot its user_id value is updated to NULL back.

All operations are performed only by UPDATE queries. Spot filling query includes WHERE job_id = @job AND user_id IS NULL LIMIT 1.

If two concurrent users try to fill a spot the user which do this earlier will fill whereas the user who tries to do this later will fail because there is no record which matches the conditions WHERE job_id = @job AND user_id IS NULL.

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top