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
1条答案
按热度按时间wwodge7n1#
This answer was substantially changed after further clarification.
Your insert query needs
HOLDLOCK
to ensure that the "emptiness" of the intended rows is locked.Exactly what insert your logic you are trying to achieve is unclear, but you can do this in a single statement with no explicit transaction necessary, just a locking hint.
Instead of a locking hint, you can also set the isolation level for the whole statement.
Note that this will cause the same isolation level for all table references though.