Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4249102
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 21, 20262026-05-21T04:21:06+00:00 2026-05-21T04:21:06+00:00

I’ve got a simple queue implementation in MS Sql Server 2008 R2. Here’s the

  • 0

I’ve got a simple queue implementation in MS Sql Server 2008 R2. Here’s the essense of the queue:

CREATE TABLE ToBeProcessed 
(
    Id BIGINT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Priority] INT DEFAULT(100) NOT NULL,
    IsBeingProcessed BIT default (0) NOT NULL,
    SomeData nvarchar(MAX) NOT null
)

I want to atomically select the top n rows ordered by the priority and the id where IsBeingProcessed is false and update those rows to say they are being processed. I thought I’d use a combination of Update, Top, Output and Order By but unfortunately you can’t use top and order by in an Update statement.

So I’ve made an in clause to restrict the update and that sub query does the order by (see below). My question is, is this whole statement atomic, or do I need to wrap it in a transaction?

DECLARE @numberToProcess INT = 2

CREATE TABLE #IdsToProcess
(
    Id BIGINT NOT null
)

UPDATE 
    ToBeProcessed
SET
    ToBeProcessed.IsBeingProcessed = 1
OUTPUT 
    INSERTED.Id 
INTO
    #IdsToProcess   
WHERE
    ToBeProcessed.Id IN 
    (
        SELECT TOP(@numberToProcess) 
            ToBeProcessed.Id 
        FROM 
            ToBeProcessed 
        WHERE
            ToBeProcessed.IsBeingProcessed = 0
        ORDER BY 
            ToBeProcessed.Id, 
            ToBeProcessed.Priority DESC)

SELECT 
    *
FROM 
    #IdsToProcess

DROP TABLE #IdsToProcess

Here’s some sql to insert some dummy rows:

INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-21T04:21:07+00:00Added an answer on May 21, 2026 at 4:21 am

    If I understand the motivation for the question you want to avoid the possibility that two concurrent transactions could both execute the sub query to get the top N rows to process then proceed to update the same rows?

    In that case I’d use this approach.

    ;WITH cte As
    (
    SELECT TOP(@numberToProcess) 
                *
            FROM 
                ToBeProcessed WITH(UPDLOCK,ROWLOCK,READPAST) 
            WHERE
                ToBeProcessed.IsBeingProcessed = 0
            ORDER BY 
                ToBeProcessed.Id, 
                ToBeProcessed.Priority DESC
    )            
    UPDATE 
        cte
    SET
        IsBeingProcessed = 1
    OUTPUT 
        INSERTED.Id 
    INTO
        #IdsToProcess  
    

    I was a bit uncertain earlier whether SQL Server would take U locks when processing your version with the sub query thus blocking two concurrent transactions from reading the same TOP N rows. This does not appear to be the case.

    Test Table

    CREATE TABLE JobsToProcess
    (
    priority INT IDENTITY(1,1),
    isprocessed BIT ,
    number INT
    )
    
    INSERT INTO JobsToProcess
    SELECT TOP (1000000) 0,0
    FROM master..spt_values v1, master..spt_values v2
    

    Test Script (Run in 2 concurrent SSMS sessions)

    BEGIN TRY
    DECLARE @FinishedMessage VARBINARY (128) = CAST('TestFinished' AS  VARBINARY (128))
    DECLARE @SynchMessage VARBINARY (128) = CAST('TestSynchronising' AS  VARBINARY (128))
    SET CONTEXT_INFO @SynchMessage
    
    DECLARE @OtherSpid int
    
    WHILE(@OtherSpid IS NULL)
    SELECT @OtherSpid=spid 
    FROM sys.sysprocesses 
    WHERE context_info=@SynchMessage and spid<>@@SPID
    
    SELECT @OtherSpid
    
    
    DECLARE @increment INT = @@spid
    DECLARE @number INT = @increment
    
    WHILE (@number = @increment AND NOT EXISTS(SELECT * FROM sys.sysprocesses WHERE context_info=@FinishedMessage))
    UPDATE JobsToProcess 
    SET @number=number +=@increment,isprocessed=1
    WHERE priority = (SELECT TOP 1 priority 
                       FROM JobsToProcess 
                       WHERE isprocessed=0 
                       ORDER BY priority DESC)
    
    SELECT * 
    FROM JobsToProcess 
    WHERE number not in (0,@OtherSpid,@@spid)
    SET CONTEXT_INFO @FinishedMessage
    END TRY
    BEGIN CATCH
    SET CONTEXT_INFO @FinishedMessage
    SELECT ERROR_MESSAGE(), ERROR_NUMBER()
    END CATCH
    

    Almost immediately execution stops as both concurrent transactions update the same row so the S locks taken whilst identifying the TOP 1 priority must get released before it aquires a U lock then the 2 transactions proceed to get the row U and X lock in sequence.

    Heap

    If a CI is added ALTER TABLE JobsToProcess ADD PRIMARY KEY CLUSTERED (priority) then deadlock occurs almost immediately instead as in this case the row S lock doesn’t get released, one transaction aquires a U lock on the row and waits to convert it to an X lock and the other transaction is still waiting to convert its S lock to a U lock.

    Clustered Index

    If the query above is changed to use MIN rather than TOP

    WHERE priority = (SELECT MIN(priority)
                       FROM JobsToProcess 
                       WHERE isprocessed=0 
                       )
    

    Then SQL Server manages to completely eliminate the sub query from the plan and takes U locks all the way.

    enter image description here

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

i got an object with contents of html markup in it, for example: string
I have just tried to save a simple *.rtf file with some websites and
I've got a string that has curly quotes in it. I'd like to replace
link Im having trouble converting the html entites into html characters, (&# 8217;) i
Seemingly simple, but I cannot find anything relevant on the web. What is the
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
I want to count how many characters a certain string has in PHP, but
I have a JSP page retrieving data and when single or double quotes are
Does anyone know how can I replace this 2 symbol below from the string
this is what i have right now Drawing an RSS feed into the php,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.