I'm using the following query to get number of unused codes - codes from AvailableCodes
table that aren't on Usage
table:
SELECT code, type
FROM
(
SELECT avc.code, avc.type,
COUNT(CASE WHEN avc.type = 'type_1' THEN 1 END) OVER () cn1,
COUNT(CASE WHEN avc.type = 'type_3' THEN 1 END) OVER () cn2,
ROW_NUMBER() OVER (PARTITION BY avc.type ORDER BY avc.id) rn
FROM AvailableCodes avc left JOIN Usage usg
ON usg.code = avc.code
WHERE usg.code IS NULL
) t
WHERE (cn1 >= 2 AND cn2 >= 1) AND
((type = 'type_1' AND rn <= 2) OR (type = 'type_3' AND rn <= 1))
ORDER BY type, code
I want to lock the selected rows from reading but allow other codes to be read in case more than one user try to reach this code simultaneously.
But I'm not sure where to put the lock part, with(rowlock, updlock, holdlock)
in a way that will lock only those selected rows from AvailableCodes
for read but allow other rows to be read.
Update: To be more clear in what I actually need to happen:
After the query above, I get an array of codes that I need to insert into the Usage
table, for example: ['111', '222', '1232']
.
Then I need to insert them to Usage
so that no other users will use these codes again.
I insert them in bulk in same query after the above query.
Update 2:
What I'm trying to implement is a system where users can select number of discount codes of each type. For example they want 5 codes from type_1
, and 3 codes from type_2
, and 10 codes from type_3
.
And each code should not be used more than once.
So my query selects the available codes in bulk and inserts them in bulk