Will (ROWLOCK,UPDLOCK,READPAST) with ORDER BY non-clustered columns work?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty{ margin-bottom:0;
}






up vote
1
down vote

favorite












I have a SQL code as below



#table creation
CREATE TABLE TAB
([i_task_id] [int] IDENTITY(1,1) NOT NULL,
[i_priority] [tinyint] NULL,
[i_status] [smallint] NULL
CONSTRAINT [PK_TAB] PRIMARY KEY CLUSTERED
(
[i_task_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

#non-clustered index on i_status
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE Name = 'IX_status' AND
OBJECT_ID = OBJECT_ID('TAB'))
BEGIN
CREATE NONCLUSTERED INDEX IX_status
ON [dbo].[TAB] (i_status)
END

#values in the table#
INSERT INTO TAB(i_priority,i_status)
VALUES (31,1),(30,1),(31,1),(20,1),(10,1)

#select query#
SELECT TOP 1 i_task_id
FROM TAB with (ROWLOCK,UPDLOCK,READPAST)
WHERE i_status = 1
ORDER BY i_priority desc,i_task_id asc


Locking does not work while executing the above query in 4 different sessions. I get result in one session where as nothing is returned in other 3 sessions.



When i tried to change the ORDER BY condition as below



 ORDER BY i_task_id asc,i_priority desc


then the query worked and returned 4 different results in 4 sessions.



My requirement is if several users try to access the same select query at the same time, there should not be any deadlock situation(i.e each user should be provided the unlocked row).Also,each user should be given different task id in different sessions.



Will the locking with order by non-clustered columns work?



Thanks for your time!










share|improve this question







New contributor




nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Does each session then update the status to something when it starts? How about when it's done? How is each session holding those locks? Can you show the transaction parts of the code too? Are you sending the i_task_id to the application and handling transaction logic there?
    – Aaron Bertrand
    yesterday












  • It's not about clustered-v-nonclustered, it's about your indexes not covering the "order by i_priority" ordering and thus causing a full index scan which in turn causes the whole table to get locked until the end of transaction.
    – sharptooth
    yesterday

















up vote
1
down vote

favorite












I have a SQL code as below



#table creation
CREATE TABLE TAB
([i_task_id] [int] IDENTITY(1,1) NOT NULL,
[i_priority] [tinyint] NULL,
[i_status] [smallint] NULL
CONSTRAINT [PK_TAB] PRIMARY KEY CLUSTERED
(
[i_task_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

#non-clustered index on i_status
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE Name = 'IX_status' AND
OBJECT_ID = OBJECT_ID('TAB'))
BEGIN
CREATE NONCLUSTERED INDEX IX_status
ON [dbo].[TAB] (i_status)
END

#values in the table#
INSERT INTO TAB(i_priority,i_status)
VALUES (31,1),(30,1),(31,1),(20,1),(10,1)

#select query#
SELECT TOP 1 i_task_id
FROM TAB with (ROWLOCK,UPDLOCK,READPAST)
WHERE i_status = 1
ORDER BY i_priority desc,i_task_id asc


Locking does not work while executing the above query in 4 different sessions. I get result in one session where as nothing is returned in other 3 sessions.



When i tried to change the ORDER BY condition as below



 ORDER BY i_task_id asc,i_priority desc


then the query worked and returned 4 different results in 4 sessions.



My requirement is if several users try to access the same select query at the same time, there should not be any deadlock situation(i.e each user should be provided the unlocked row).Also,each user should be given different task id in different sessions.



Will the locking with order by non-clustered columns work?



Thanks for your time!










share|improve this question







New contributor




nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Does each session then update the status to something when it starts? How about when it's done? How is each session holding those locks? Can you show the transaction parts of the code too? Are you sending the i_task_id to the application and handling transaction logic there?
    – Aaron Bertrand
    yesterday












  • It's not about clustered-v-nonclustered, it's about your indexes not covering the "order by i_priority" ordering and thus causing a full index scan which in turn causes the whole table to get locked until the end of transaction.
    – sharptooth
    yesterday













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have a SQL code as below



#table creation
CREATE TABLE TAB
([i_task_id] [int] IDENTITY(1,1) NOT NULL,
[i_priority] [tinyint] NULL,
[i_status] [smallint] NULL
CONSTRAINT [PK_TAB] PRIMARY KEY CLUSTERED
(
[i_task_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

#non-clustered index on i_status
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE Name = 'IX_status' AND
OBJECT_ID = OBJECT_ID('TAB'))
BEGIN
CREATE NONCLUSTERED INDEX IX_status
ON [dbo].[TAB] (i_status)
END

#values in the table#
INSERT INTO TAB(i_priority,i_status)
VALUES (31,1),(30,1),(31,1),(20,1),(10,1)

#select query#
SELECT TOP 1 i_task_id
FROM TAB with (ROWLOCK,UPDLOCK,READPAST)
WHERE i_status = 1
ORDER BY i_priority desc,i_task_id asc


Locking does not work while executing the above query in 4 different sessions. I get result in one session where as nothing is returned in other 3 sessions.



When i tried to change the ORDER BY condition as below



 ORDER BY i_task_id asc,i_priority desc


then the query worked and returned 4 different results in 4 sessions.



My requirement is if several users try to access the same select query at the same time, there should not be any deadlock situation(i.e each user should be provided the unlocked row).Also,each user should be given different task id in different sessions.



Will the locking with order by non-clustered columns work?



Thanks for your time!










share|improve this question







New contributor




nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I have a SQL code as below



#table creation
CREATE TABLE TAB
([i_task_id] [int] IDENTITY(1,1) NOT NULL,
[i_priority] [tinyint] NULL,
[i_status] [smallint] NULL
CONSTRAINT [PK_TAB] PRIMARY KEY CLUSTERED
(
[i_task_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

#non-clustered index on i_status
IF NOT EXISTS(SELECT 1 FROM sys.indexes WHERE Name = 'IX_status' AND
OBJECT_ID = OBJECT_ID('TAB'))
BEGIN
CREATE NONCLUSTERED INDEX IX_status
ON [dbo].[TAB] (i_status)
END

#values in the table#
INSERT INTO TAB(i_priority,i_status)
VALUES (31,1),(30,1),(31,1),(20,1),(10,1)

#select query#
SELECT TOP 1 i_task_id
FROM TAB with (ROWLOCK,UPDLOCK,READPAST)
WHERE i_status = 1
ORDER BY i_priority desc,i_task_id asc


Locking does not work while executing the above query in 4 different sessions. I get result in one session where as nothing is returned in other 3 sessions.



When i tried to change the ORDER BY condition as below



 ORDER BY i_task_id asc,i_priority desc


then the query worked and returned 4 different results in 4 sessions.



My requirement is if several users try to access the same select query at the same time, there should not be any deadlock situation(i.e each user should be provided the unlocked row).Also,each user should be given different task id in different sessions.



Will the locking with order by non-clustered columns work?



Thanks for your time!







sql-server locking deadlock






share|improve this question







New contributor




nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked yesterday









nikitha

61




61




New contributor




nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






nikitha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • Does each session then update the status to something when it starts? How about when it's done? How is each session holding those locks? Can you show the transaction parts of the code too? Are you sending the i_task_id to the application and handling transaction logic there?
    – Aaron Bertrand
    yesterday












  • It's not about clustered-v-nonclustered, it's about your indexes not covering the "order by i_priority" ordering and thus causing a full index scan which in turn causes the whole table to get locked until the end of transaction.
    – sharptooth
    yesterday


















  • Does each session then update the status to something when it starts? How about when it's done? How is each session holding those locks? Can you show the transaction parts of the code too? Are you sending the i_task_id to the application and handling transaction logic there?
    – Aaron Bertrand
    yesterday












  • It's not about clustered-v-nonclustered, it's about your indexes not covering the "order by i_priority" ordering and thus causing a full index scan which in turn causes the whole table to get locked until the end of transaction.
    – sharptooth
    yesterday
















Does each session then update the status to something when it starts? How about when it's done? How is each session holding those locks? Can you show the transaction parts of the code too? Are you sending the i_task_id to the application and handling transaction logic there?
– Aaron Bertrand
yesterday






Does each session then update the status to something when it starts? How about when it's done? How is each session holding those locks? Can you show the transaction parts of the code too? Are you sending the i_task_id to the application and handling transaction logic there?
– Aaron Bertrand
yesterday














It's not about clustered-v-nonclustered, it's about your indexes not covering the "order by i_priority" ordering and thus causing a full index scan which in turn causes the whole table to get locked until the end of transaction.
– sharptooth
yesterday




It's not about clustered-v-nonclustered, it's about your indexes not covering the "order by i_priority" ordering and thus causing a full index scan which in turn causes the whole table to get locked until the end of transaction.
– sharptooth
yesterday










1 Answer
1






active

oldest

votes

















up vote
4
down vote













I would opt for marking the row as "in process" (e.g. having a status for the equivalent of "checked out") as opposed to relying solely on row locking:



;WITH x AS 
(
SELECT TOP (1) i_task_id, i_status
FROM dbo.TAB WITH (ROWLOCK,UPDLOCK,READPAST)
WHERE i_status = 1
ORDER BY i_priority DESC,i_task_id ASC
)
UPDATE x SET i_status = 2 -- in process? locked?
OUTPUT inserted.i_task_id
WHERE i_status = 1;


No blocking or deadlocking in my tests. The 6th session won't block or deadlock either, it will just return no rows.






share|improve this answer





















    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "182"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    nikitha is a new contributor. Be nice, and check out our Code of Conduct.










     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f222334%2fwill-rowlock-updlock-readpast-with-order-by-non-clustered-columns-work%23new-answer', 'question_page');
    }
    );

    Post as a guest
































    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    down vote













    I would opt for marking the row as "in process" (e.g. having a status for the equivalent of "checked out") as opposed to relying solely on row locking:



    ;WITH x AS 
    (
    SELECT TOP (1) i_task_id, i_status
    FROM dbo.TAB WITH (ROWLOCK,UPDLOCK,READPAST)
    WHERE i_status = 1
    ORDER BY i_priority DESC,i_task_id ASC
    )
    UPDATE x SET i_status = 2 -- in process? locked?
    OUTPUT inserted.i_task_id
    WHERE i_status = 1;


    No blocking or deadlocking in my tests. The 6th session won't block or deadlock either, it will just return no rows.






    share|improve this answer

























      up vote
      4
      down vote













      I would opt for marking the row as "in process" (e.g. having a status for the equivalent of "checked out") as opposed to relying solely on row locking:



      ;WITH x AS 
      (
      SELECT TOP (1) i_task_id, i_status
      FROM dbo.TAB WITH (ROWLOCK,UPDLOCK,READPAST)
      WHERE i_status = 1
      ORDER BY i_priority DESC,i_task_id ASC
      )
      UPDATE x SET i_status = 2 -- in process? locked?
      OUTPUT inserted.i_task_id
      WHERE i_status = 1;


      No blocking or deadlocking in my tests. The 6th session won't block or deadlock either, it will just return no rows.






      share|improve this answer























        up vote
        4
        down vote










        up vote
        4
        down vote









        I would opt for marking the row as "in process" (e.g. having a status for the equivalent of "checked out") as opposed to relying solely on row locking:



        ;WITH x AS 
        (
        SELECT TOP (1) i_task_id, i_status
        FROM dbo.TAB WITH (ROWLOCK,UPDLOCK,READPAST)
        WHERE i_status = 1
        ORDER BY i_priority DESC,i_task_id ASC
        )
        UPDATE x SET i_status = 2 -- in process? locked?
        OUTPUT inserted.i_task_id
        WHERE i_status = 1;


        No blocking or deadlocking in my tests. The 6th session won't block or deadlock either, it will just return no rows.






        share|improve this answer












        I would opt for marking the row as "in process" (e.g. having a status for the equivalent of "checked out") as opposed to relying solely on row locking:



        ;WITH x AS 
        (
        SELECT TOP (1) i_task_id, i_status
        FROM dbo.TAB WITH (ROWLOCK,UPDLOCK,READPAST)
        WHERE i_status = 1
        ORDER BY i_priority DESC,i_task_id ASC
        )
        UPDATE x SET i_status = 2 -- in process? locked?
        OUTPUT inserted.i_task_id
        WHERE i_status = 1;


        No blocking or deadlocking in my tests. The 6th session won't block or deadlock either, it will just return no rows.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered yesterday









        Aaron Bertrand

        148k18280477




        148k18280477






















            nikitha is a new contributor. Be nice, and check out our Code of Conduct.










             

            draft saved


            draft discarded


















            nikitha is a new contributor. Be nice, and check out our Code of Conduct.













            nikitha is a new contributor. Be nice, and check out our Code of Conduct.












            nikitha is a new contributor. Be nice, and check out our Code of Conduct.















             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f222334%2fwill-rowlock-updlock-readpast-with-order-by-non-clustered-columns-work%23new-answer', 'question_page');
            }
            );

            Post as a guest




















































































            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?