question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

MSSQL, UPDLOCK hint

See original GitHub issue

Hi,

could you please add an UPDLOCK hint into generated SQL merge query?

currently an upsert operation is translated into this SQL code for MSSQL server.

MERGE INTO [StateChangeSnapshots] WITH (HOLDLOCK) AS [T] USING...

IMHO prefered query should be this:

MERGE INTO [StateChangeSnapshots] WITH (UPDLOCK, HOLDLOCK) AS [T] USING...

HOLDLOCK itself is not good enough to avoid deadlocks, this only imply that a serializable isolation level should be used for that table. And IL serializable itself does not prevent from deadlocks.

As you can see here: image

I have plenty of such errors in my scenario.

You can simulate that error yourself with SSMS.

--first tab (connection)

SET TRAN ISOLATION LEVEL READ COMMITTED; --sql server default

DROP TABLE IF EXISTS ##myTable;
CREATE TABLE ##myTable(Id INT)

INSERT INTO ##myTable(Id) VALUES (1);

BEGIN TRAN t1

SELECT * FROM ##myTable with(UPDLOCK, HOLDLOCK) WHERE Id = 1;

--1) run to up here only, then switch to second connection (second tab in SSMS)

UPDATE MT SET Id = 2 FROM ##myTable MT WHERE Id = 1

--3) run UPDATE statement only (transaction for it should still be running)

--AS A RESULT one CONNECTION finishes and the second one ends up with a deadlock

COMMIT TRAN t1
--second tab (connection)

SET TRAN ISOLATION LEVEL READ COMMITTED; --sql server default

BEGIN TRAN t1

SELECT * FROM ##myTable with(UPDLOCK, HOLDLOCK) WHERE Id = 1;

UPDATE MT SET Id = 2 FROM ##myTable MT WHERE Id = 1

--2) run to here only

COMMIT TRAN t1

image

image

UPDLOCK does the thing. If you use it, then that query reserves those entries for its further updates.

See

image

image

In this case the second query stops (in “select” phase) and waits for the first query till it finishes the update operation and commits its transaction (or do a rollback), only then processing of the second query continues.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
martinrulfcommented, Dec 10, 2020

Nice and thanks, I am glad I could provide some hints 😃

The Merge is very complex operation as you can see if you check the execution plan.

Probably you would be able to improve your first solution significantly (merge) by adding an appropriate index. (Which could also avoid the deadlocks)

BR

1reaction
IanNorriscommented, Dec 9, 2020

Wow, that’s a complex solution. There’s a few nice tricks in there that I wasn’t aware of, so I’m going to dig into those.

Here’s the query I ended up with:

BEGIN TRY INSERT INTO [Table] (…) VALUES( … ); END TRY BEGIN CATCH UPDATE [Table] SET … WHERE [Index1] = @index1 AND [Index2] = @index2; END CATCH

It definitively resolved the perf issues I was seeing as well and I’ve not seen a hint of the index deadlock or index collision issues the Upsert was to avoid. The Upsert with MAXDOP was taking 13h of compute time, the new version takes 13s for that same data set. This may be a viable solution for integration into the library, or for those trying to solve this problem for themselves.

Read more comments on GitHub >

github_iconTop Results From Across the Web

SQL Server UPDATE lock and UPDLOCK Table Hints
The UPDLOCK tablehint is used to impose an update lock on a resource until the transaction completes. Thus, if a transaction reads data...
Read more >
Table Hints (Transact-SQL) - SQL Server
Specifies that update locks are to be taken and held until the transaction completes. UPDLOCK takes update locks for read operations only at...
Read more >
In Micrsoft SQL is an UPDLOCK hint sufficient to avoid ...
1 Answer 1 ... In in the default READ COMMITTED isolation level, the UPDLOCK will be released when the statement completes. Specify UPDLOCK, ......
Read more >
sql server - Side effects of using updlock lock hint?
I was just exploring UPDLOCK hint in SQL-Server 2008 and I found it is very useful in avoiding certain deadlock scenarios.
Read more >
Duration of locks when using WITH (UPDLOCK)
The "UPDLOCK" locking hint is used when doing a select for update i.e. when you are using pessimistic concurrency model and you want...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found