Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

1 Answer
1

The exact behaviour of concurrent modifications depends, in part, on the access path chosen by SQL Server to locate records to change.

If SQL Server uses the clustered index to locate data to change, locks will generally be taken on clustered index keys (and/or pages, etc.). If SQL Server locates rows to change using a nonclustered index, locks will be taken on the nonclustered index. In both cases, exclusive locks are also generally taken on the clustered index before the modification is actually performed.

Anticipating locking behaviour can be a fun and educational exercise, but it often the wrong question to ask. If you are experiencing blocking on locks where it does not seem necessary, then it might be the right question, but it is a very advanced one, requiring detailed internal knowledge to fully explain. I'll show an example based on your data later on.

Most often, the real question is "which isolation level should I use?". Locks are an implementation detail, used to provide the guarantees offered by the various isolation levels. The guarantees are the important thing. You should understand the different behaviours that are possible under each isolation level, and then make an informed choice. Please refer to that link for all the details.

When modifying data, RCSI behaves the same as standard READ COMMITTED. It will block if it needs to read something that is currently locked by another session's uncommitted changes. Once the blocking session commits or rolls back its changes, the blocked update continues, reading the committed values present at the time the blocking lock was released. This behaviour is required to prevent "lost updates", which are not allowed under any isolation level supported by SQL Server.

The following demo shows that the precise blocking behaviour depends on which locks are needed according to the query plan selected by the optimizer. In some cases, the update will block, in other cases, it will not. SQL Server always respects the guarantees provided by the user's isolation level, regardless of the implementation-defined locking behaviour.