|
database
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
A little advice about locks with SQL 2000I am hoping someone can give me a little advice about locks. I have just finished reading a chapter about them in a reference book and i am now more confused than when I started. What I want to do is simple, i hope. I have multiple users selecting from the same table, I am worried about 2 users getting the same result, which would be very bad, I just need to find away to stop this from happening. My set up is real simple. The SP is below: Basically A user will call this SP the first part brings back a row, then updates that table and sets a field to 1, which is used in selecting the initial row. Basically, I am worried that someone will have selected the row and in between that persons SP updating the table, another user come along and then get the same row, and then try to update the same table. My program will then perform the same functionon the identical data, which is bad. I know that a lot of books, say this is unlikely, but my app is such that this SP will be hit by hundreds of users, every second. in an ideal world, a user would not be able to execute the SP, until it has finished executing the last, but I still have to be able to process hundreds of requests per second, without having massive bottle necks. Any help would be much appreciated. CREATE PROCEDURE [dbo].[Engine_Fetch_List] AS DECLARE @client_id int DECLARE @url_id int /*LOCK THIS TABLE UNTIL IT HAS BEEN UPDATED TO STOP ANYONE ELSE FROM SELECTING IT*/ SELECT TOP 1 @client_id = l.client_id, @url_id = l.url_id FROM dbo.tbl_client_fetch_list l WHERE (l.updating = 0) AND (l.updated = 0) GROUP BY l.client_id, l.url_id ORDER BY l.client_id /*SET THE UPDATING FLAG, TO STOP ANYONE ELSE FROM SELECTING THIS URL*/ UPDATE dbo.tbl_client_fetch_list SET updating = 1 WHERE client_id = @client_id AND url_id = @url_id /* REMOVE LOCK*/ GO Chris
DECLARE @pr INT BEGIN TRANSACTION SELECT @pr =MAX(col) FROM Table WITH (UPDLOCK,HOLDLOCK) UPDATE Table1 SET col =@pr WHERE blabala COMMIT TRANSACTION I'd recommend you to search on interent an explanation posted by Brian Selzer about those lock hints or please refer for the details in BOL. Show quote "ChrisDangerfield" <ch***@dangerfieldbrothers.co.uk> wrote in message news:1136639527.280129.256420@g14g2000cwa.googlegroups.com... > Hi there, > > I am hoping someone can give me a little advice about locks. > > I have just finished reading a chapter about them in a reference book > and i am now more confused than when I started. > > What I want to do is simple, i hope. > > I have multiple users selecting from the same table, I am worried about > 2 users getting the same result, which would be very bad, I just need > to find away to stop this from happening. > > My set up is real simple. > > The SP is below: > > Basically A user will call this SP the first part brings back a row, > then updates that table and sets a field to 1, which is used in > selecting the initial row. Basically, I am worried that someone will > have selected the row and in between that persons SP updating the > table, another user come along and then get the same row, and then try > to update the same table. My program will then perform the same > functionon the identical data, which is bad. > > I know that a lot of books, say this is unlikely, but my app is such > that this SP will be hit by hundreds of users, every second. > > in an ideal world, a user would not be able to execute the SP, until it > has finished executing the last, but I still have to be able to process > hundreds of requests per second, without having massive bottle necks. > > Any help would be much appreciated. > > CREATE PROCEDURE [dbo].[Engine_Fetch_List] > AS > > DECLARE @client_id int > DECLARE @url_id int > > /*LOCK THIS TABLE UNTIL IT HAS BEEN UPDATED TO STOP ANYONE ELSE FROM > SELECTING IT*/ > > SELECT TOP 1 @client_id = l.client_id, @url_id = l.url_id > FROM dbo.tbl_client_fetch_list l > WHERE (l.updating = 0) AND (l.updated = 0) > GROUP BY l.client_id, l.url_id > ORDER BY l.client_id > > /*SET THE UPDATING FLAG, TO STOP ANYONE ELSE FROM SELECTING THIS URL*/ > UPDATE dbo.tbl_client_fetch_list SET updating = 1 WHERE client_id = > @client_id AND url_id = @url_id > > /* REMOVE LOCK*/ > GO > Hello Chris,
Usually the best way is just to start with the UPDATE, if you used SQL 2005 you could also use the OUTPUT clause of the UPDATE. This way in this example you don't need to worry about locks etc. ex: CREATE PROCEDURE [dbo].[Engine_Fetch_List] AS DECLARE @client_id int DECLARE @url_id int /*LOCK THIS TABLE UNTIL IT HAS BEEN UPDATED TO STOP ANYONE ELSE FROM SELECTING IT*/ /*SET THE UPDATING FLAG, TO STOP ANYONE ELSE FROM SELECTING THIS URL*/ SET ROWCOUNT 1 -- Only update one row. UPDATE dbo.tbl_client_fetch_list SET @client_id = client_id -- Here you want to fecth the table PK to search on that in any SELECTs below. ,@url_id = url_id ,updating = 1 WHERE updating = 0 AND updated = 0 SET ROWCOUNT 0 -- Do any selects that you need here, you may (not always) want to open a tran. before the update to hold the X-lock it took. HTH Tobias |
|||||||||||||||||||||||