In my recent issues.. I have noticed a dead lock killing an update statement rather than a select command which was locked in it.
The SELECT's isolation level was at the database default, which is read committed snapshot isolation.
The SELECT is part of a transaction in our ETL.
Best Answer
Yes, SELECTs need locks, and they can win deadlocks if they're involved in a transaction that's done a lot of work leading up to that point.
To see it, go into a database with RCSI turned on, and create a couple of tables - only one of them will have data in it:
Then start a transaction that does a lot of work on the table with data:
Now start a NEW TAB in SSMS so that you're in a different session - we're going to call this Window #2 - and run:
Both transactions in the two different windows are working on two different tables. So far, so good. Now continuing in Window #2, run an update on Window #1's table:
That update just hangs - he's blocked. Don't cancel him - leave him running. He's blocked by the Window #1 transaction. In RCSI, writers still block each other when they're trying to work on the same rows.
Switch back over to Window #1, and run:
And count to 5. Within 5 seconds, SQL Server wakes up the deadlock monitor, who looks around, finds that these two queries are blocking each other, and...the select wins! The select returns data, and the update's window says:
Why? Because SQL Server by default chooses the victim by whichever transaction is the easiest to roll back. In our case, Window #1 had done a lot of work already, updating thousands of rows, whereas Window #2 had done just a tiny amount of work.
This is a contrived example in order to teach the lesson quickly - your scenario probably doesn't involve an ALTER TABLE command. Still, the same theory applies.