A rowlock is only going to lock the row.
Moving to tablelock would impact performance.
I would add a status column to A of InProcess.
Then in a transaction mark that to true.
So your query would also have a where A.InProcess = false.
문제
I have much information in the table named "A". The table named "B" is empty.
I get 500 rows from table A, which are not in the table "B":
SELECT TOP 500 * FROM A WHERE
NOT EXISTS (
SELECT * FROM B WHERE
(
A.id1=B.id1 AND A.id2=B.id2
)
)
Everything works well, But I have one problem here.
I have a web application, which calls that SQL query. Imagine that 200 people together call my application, there will be duplicates in the table named "B". Sow how can I lock those rows?
Is this correct?
SELECT TOP 500 * FROM A WITH (ROWLOCK) WHERE
NOT EXISTS (
SELECT * FROM B WITH (ROWLOCK) WHERE
(
A.id1=B.id1 AND A.id2=B.id2
)
)
FOR MORE CLEARLY:
imagine that when you open my web application, page calls (for instance Servlet or PHP) SQL query.
If many person together open my application there is threading problem. while open query is writing data to the table named B, another query parallely doing same thing.
Threading problem: while one thread read 500 row, another thread may read the same data because first thread is still writing data at this moment and has not finished it yet.
thread 1 read that data from table "A": 1,2,3,4,5,6,7 ... 500
thread 1 wriote that data to the table named "B": 1,2,3,4,5,6,7,...495
thread 1 is not finished and thread 2 read data that from table "a": 496, 497 .. 500 ,.... 995
thread 2 write 496, 497 .. 500 ,.... 995
then again thread 1 write data
495 .. 500
For exampl
해결책
A rowlock is only going to lock the row.
Moving to tablelock would impact performance.
I would add a status column to A of InProcess.
Then in a transaction mark that to true.
So your query would also have a where A.InProcess = false.
다른 팁
I need to point out that the queries that you have posted won't actually write anything to Table B.
That being said, if you're just looking to lock down rows that are being worked on in Table A, I would suggest adding a status column to the table and using a stored procedure similar to the following.
DECLARE @Results TABLE
(
id1 int NOT NULL,
id2 int NOT NULL --Assuming these are ints
)
UPDATE TOP (500) A with (ROWLOCK, READPAST)
SET [Status] = 'InProcess'
OUTPUT inserted.id1,
inserted.id2
INTO @Results
WHERE [Status] <> 'InProcess'
SELECT * FROM @Results temp
INNER JOIN A
ON A.id1 = temp.id1 AND A.id2=temp.id2
I have used this method when I had multiple workers coming to a single table looking for tasks to do.
The keys points here are:
There's a lot going on here, and maybe you don't need all this, but this is the method I found to give me high concurrency while preventing race conditions.