You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/relational-databases/performance/optimized-locking.md
+12-12Lines changed: 12 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,9 +80,9 @@ When multiple transactions are allowed to access the same data concurrently, the
80
80
81
81
### Optimized locking and transaction ID (TID) locking
82
82
83
-
Every row in the Database Engine internally contains a transaction ID (TID) when row versioning is in use. This TID is persisted on disk. Every transaction modifying a row will stamp that row with its TID.
83
+
Every row in the Database Engine internally contains a transaction ID (TID) when row versioning is in use. This TID is persisted on disk. Every transaction modifying a row stamps that row with its TID.
84
84
85
-
With TID locking, instead of taking the lock on the key of the row, a lock is taken on the TID of the row. The modifying transaction will hold an X lock on its TID. Other transactions will acquire an S lock on the TID to check if the first transaction is still active. With TID locking, page and row locks continue to be taken for updates, but each page and row lock is released as soon as each row is updated. The only lock held until end of transaction is the X lock on the TID resource, replacing page and row (key) locks as demonstrated in the next demo. (Other standard database and object locks are not affected by optimized locking.)
85
+
With TID locking, instead of taking the lock on the key of the row, a lock is taken on the TID of the row. The modifying transaction holds an X lock on its TID. Other transactions acquire an S lock on the TID to check if the first transaction is still active. With TID locking, page and row locks continue to be taken for updates, but each page and row lock is released as soon as each row is updated. The only lock held until end of transaction is the X lock on the TID resource, replacing page and row (key) locks as demonstrated in the next demo. (Other standard database and object locks are not affected by optimized locking.)
86
86
87
87
Optimized locking helps to reduce lock memory as very few locks are held for large transactions. In addition, optimized locking also avoids lock escalations. This allows other concurrent transactions to access the table.
88
88
@@ -148,7 +148,7 @@ The behavior of blocking changes with optimized locking in the previous example.
148
148
149
149
However, with optimized locking, Session 2 will not be blocked as the latest committed version of row 1 contains a=1, which does not satisfy the predicate of Session 2.
150
150
151
-
If the predicate is satisfied, we wait for any active transaction on the row to finish. If we had to wait for the S TID lock, the row might have changed, and the latest committed version might have changed. In that case, instead of aborting the transaction due to an update conflict, the Database Engine will retry the predicate evaluation on the same row. If the predicate qualifies upon retry, the row will be updated.
151
+
If the predicate is satisfied, we wait for any active transaction on the row to finish. If we had to wait for the S TID lock, the row might have changed, and the latest committed version might have changed. In that case, instead of aborting the transaction due to an update conflict, the Database Engine retries the predicate evaluation on the same row. If the predicate qualifies upon retry, the row will be updated.
152
152
153
153
Consider the following example when a predicate change is automatically retried:
154
154
@@ -196,7 +196,7 @@ Without LAQ, transaction T2 will be blocked and wait for the transaction T1 to c
196
196
197
197
After both transactions commit, table `t1` will contain the following rows:
198
198
199
-
```
199
+
```output
200
200
a | b
201
201
1 | 3
202
202
```
@@ -207,7 +207,7 @@ With LAQ, transaction T2 will use the latest committed version of the row b (`b`
207
207
208
208
After both transactions commit, table `t1` will contain the following rows:
209
209
210
-
```
210
+
```output
211
211
a | b
212
212
1 | 2
213
213
```
@@ -221,9 +221,9 @@ To support monitoring and troubleshooting of blocking and deadlocking with optim
221
221
222
222
- Wait types for optimized locking
223
223
-`XACT` wait types and resource descriptions in [sys.dm_os_wait_stats (Transact-SQL)](../system-dynamic-management-views/sys-dm-os-wait-stats-transact-sql.md#lck_m_s_xact):
224
-
- `LCK_M_S_XACT_READ` - Occurs when a task is waiting for a shared lock on an XACT `wait_resource` type, with an intent to read.
225
-
- `LCK_M_S_XACT_MODIFY` - Occurs when a task is waiting for a shared lock on an XACT `wait_resource` type, with an intent to modify.
226
-
- `LCK_M_S_XACT` - Occurs when a task is waiting for a shared lock on an XACT `wait_resource` type, where the intent cannot be inferred. Rare.
224
+
- `LCK_M_S_XACT_READ` - Occurs when a task is waiting for a shared lock on an `XACT``wait_resource` type, with an intent to read.
225
+
- `LCK_M_S_XACT_MODIFY` - Occurs when a task is waiting for a shared lock on an `XACT``wait_resource` type, with an intent to modify.
226
+
- `LCK_M_S_XACT` - Occurs when a task is waiting for a shared lock on an `XACT``wait_resource` type, where the intent cannot be inferred. Rare.
227
227
- Locking resources visibility
228
228
-`XACT` locking resources. For more information, see `resource_description` in [sys.dm_tran_locks (Transact-SQL)](../system-dynamic-management-views/sys-dm-tran-locks-transact-sql.md).
229
229
- Wait resource visibility
@@ -241,13 +241,13 @@ To maximize the benefits of optimized locking, it is recommended to enable [read
241
241
ALTERDATABASE databasename SET READ_COMMITTED_SNAPSHOT ON;
242
242
```
243
243
244
-
In [!INCLUDE [asdb](../../includes/ssazure-sqldb.md)], RCSI is enabled by default and read committed is the default isolation level. With RCSI enabled and when using read committed isolation level, readers don't block writers and writers don't block readers. Readers read a version of the row from the snapshot taken at the start of the query. With LAQ, writers will qualify rows per the predicate based on the latest committed version of the row without acquiring U locks. With LAQ, a query will wait only if the row qualifies and there is an active write transaction on that row. Qualifying based on the latest committed version and locking only the qualified rows reduces blocking and increases concurrency.
244
+
In [!INCLUDE [asdb](../../includes/ssazure-sqldb.md)], RCSI is enabled by default and read committed is the default isolation level. With RCSI enabled and when using read committed isolation level, readers don't block writers, and writers don't block readers. Readers read a version of the row from the snapshot taken at the start of the query. With LAQ, writers will qualify rows per the predicate based on the latest committed version of the row without acquiring U locks. With LAQ, a query will wait only if the row qualifies and there is an active write transaction on that row. Qualifying based on the latest committed version and locking only the qualified rows reduces blocking and increases concurrency.
245
245
246
246
In addition to reduced blocking, the lock memory required will be reduced. This is because readers don't take any locks, and writers take only short duration locks, instead of locks that expire at the end of the transaction. When using stricter isolation levels like repeatable read or serializable, the Database Engine is forced to hold row and page locks until the end of the transaction, for both readers and writers, resulting in increased blocking and lock memory.
247
247
248
248
### Avoid locking hints
249
249
250
-
While [table and query hints](../../t-sql/queries/hints-transact-sql.md) are honored, they reduce the benefit of optimized locking. Lock hints like UPDLOCK, READCOMMITTEDLOCK, XLOCK, HOLDLOCK, etc., in your queries reduce the full benefits of optimized locking. Having such lock hints in the queries forces the Database Engine to take row/page locks and hold them until the end of the transaction, to honor the intent of the lock hints. Some applications have logic where lock hints are needed, for example when reading a row with select with UPDLOCK and then updating it later. We recommend using lock hints only where needed.
250
+
While [table and query hints](../../t-sql/queries/hints-transact-sql.md) are honored, they reduce the benefit of optimized locking. Lock hints like `UPDLOCK`, `READCOMMITTEDLOCK`, `XLOCK`, `HOLDLOCK`, etc., in your queries reduce the full benefits of optimized locking. Having such lock hints in the queries forces the Database Engine to take row/page locks and hold them until the end of the transaction, to honor the intent of the lock hints. Some applications have logic where lock hints are needed, for example when reading a row with select with `UPDLOCK` and then updating it later. We recommend using lock hints only where needed.
251
251
252
252
With optimized locking, there are no restrictions on existing queries and queries do not need to be rewritten. Queries that are not using hints will benefit most from optimized locking.
253
253
@@ -279,7 +279,7 @@ FROM t3 WITH (REPEATABLEREAD)
279
279
INNER JOIN t4 ONt3.a=t4.a;
280
280
```
281
281
282
-
In the previous query example, only table `t3` will use the repeatable read isolation level, and will hold locks until the end of the transaction. Other updates to `t3` can still benefit from optimized locking. The same applies to the HOLDLOCK hint.
282
+
In the previous query example, only table `t3` will use the repeatable read isolation level, and will hold locks until the end of the transaction. Other updates to `t3` can still benefit from optimized locking. The same applies to the `HOLDLOCK` hint.
283
283
284
284
## Frequently asked questions (FAQ)
285
285
@@ -311,7 +311,7 @@ If ADR is disabled, optimized locking is automatically disabled as well.
311
311
312
312
### What if I want to force queries to block despite optimized locking?
313
313
314
-
For customers using RCSI, to force blocking between two queries when optimized locking is enabled, use the READCOMMITTEDLOCK query hint.
314
+
For customers using RCSI, to force blocking between two queries when optimized locking is enabled, use the `READCOMMITTEDLOCK` query hint.
0 commit comments