Will (ROWLOCK,UPDLOCK,READPAST) with ORDER BY non-clustered columns work?
Clash Royale CLAN TAG#URR8PPP
.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!
sql-server locking deadlock
New contributor
add a comment |
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!
sql-server locking deadlock
New contributor
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 thei_task_id
to the application and handling transaction logic there?
– Aaron Bertrand♦
18 hours ago
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
16 hours ago
add a comment |
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!
sql-server locking deadlock
New contributor
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
sql-server locking deadlock
New contributor
New contributor
New contributor
asked 18 hours ago
nikitha
61
61
New contributor
New contributor
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 thei_task_id
to the application and handling transaction logic there?
– Aaron Bertrand♦
18 hours ago
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
16 hours ago
add a comment |
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 thei_task_id
to the application and handling transaction logic there?
– Aaron Bertrand♦
18 hours ago
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
16 hours ago
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♦
18 hours ago
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♦
18 hours ago
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
16 hours ago
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
16 hours ago
add a comment |
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.
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered 18 hours ago
Aaron Bertrand♦
148k18279476
148k18279476
add a comment |
add a comment |
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.
nikitha is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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♦
18 hours ago
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
16 hours ago