Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sql Server Ignore rowlock hint

This is a general question about how to lock range of values (and nothing else!) when they are not exists in table yet. The trigger for the question was that I want to do "insert if not exists", I don't want to use MERGE because I need to support SQL Server 2005.

In the first connection I:

  1. begin transaction
  2. select data from a table using (SERIALIZABLE, ROWLOCK) + where clause to respecify range
  3. wait...

In the second connection, I insert data to the table with values that do not match the where clause in the first connection

I would expect that the second connection won't be affected by the first one, but it finishes only after I commit (or rollback) the first connection's transaction.

What am I missing?

Here is my test code:

First create this table:

CREATE TABLE test
(
    VALUE nvarchar(100)
)

Second, open new query window sql server managements studio and execute the following:

BEGIN TRANSACTION;
SELECT *
FROM  test WITH (SERIALIZABLE,ROWLOCK)
WHERE value = N'a';

Third, open another new query window and execute the following:

INSERT INTO test VALUES (N'b');

Notice that the second query doesn't ends until the transaction in the first window ends

like image 498
Amstaf Avatar asked Dec 04 '11 10:12

Amstaf


1 Answers

You are missing an index on VALUE.

Without that SQL Server has nothing to take a key range lock on and will lock the whole table in order to lock the range.

Even when the index is added however you will still encounter blocking with the scenario in your question. The RangeS-S lock doesn't lock the specific range given in your query. Instead it locks the range between the keys either side of the selected range.

When there are no such keys either side the range lock extends to infinity. You would need to add a value between a and b (for example aa) to prevent this happening in your test and the insert of b being blocked.

See Bonus Appendix: Range Locks in this article for more about this.

like image 80
Martin Smith Avatar answered Sep 22 '22 18:09

Martin Smith