If you’ve designed your SQL code intelligently and implemented a sensible indexing strategy, there’s a good chance your queries will “fly”, when tested in isolation. In the real world, however, where multiple processes can access the same data at the same time, SQL Server often has to make one process wait, sacrificing concurrency and performance in order that all processes can succeed without destroying data integrity.

Transactions are at the heart of concurrency. I explain their ACID properties, the transaction isolation levels that dictate acceptable behaviors when multiple transactions access the same data simultaneously, and SQL Server’s optimistic and pessimistic models for mediating concurrent access.

Pessimistic concurrency, SQL Server’s default, uses locks to avoid concurrency problems. I explain all the different locks and their compatibility. I show how to control locking with hints and bound connections, and how to troubleshoot excessive blocki …