Skip to content

Commit 5908084

Browse files
authored
Merge pull request #1453 from segovoni/sgovoni/samples/features/optimized-locking
Optimized Locking - Transaction ID (TID) Locking internals sample
2 parents f0df934 + 412778b commit 5908084

3 files changed

Lines changed: 210 additions & 4 deletions

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
<!-- Always leave the MS logo -->
2+
![](https://github.com/microsoft/sql-server-samples/blob/master/media/solutions-microsoft-logo-small.png)
3+
4+
# Optimized Locking: Transaction ID (TID) locking internals
5+
6+
This sample describes how to read and interpret the Transaction ID (TID) stored in row data pages.
7+
8+
## Background
9+
10+
Optimized Locking is a database engine feature designed to reduce the memory used for lock management, decrease the phenomenon known as lock escalation, and increase workload concurrency.
11+
12+
Optimized Locking depends on two technologies that have long been part of the SQL Server engine:
13+
- [Accelerated Database Recovery (ADR)](https://learn.microsoft.com/sql/relational-databases/accelerated-database-recovery-concepts) is a required prerequisite for enabling Optimized Locking
14+
- [Read Committed Snapshot Isolation (RCSI)](https://learn.microsoft.com/sql/t-sql/statements/set-transaction-isolation-level-transact-sql) is not a strict requirement, but allows full benefit from Optimized Locking
15+
16+
Optimized Locking is based on two key mechanisms:
17+
- Transaction ID (TID) locking
18+
- Lock After Qualification (LAQ)
19+
20+
### What is the Transaction ID (TID)?
21+
22+
The Transaction ID (TID) is a unique transaction identifier.
23+
24+
When a [row-versioning based isolation level](https://learn.microsoft.com/en-us/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide#Row_versioning) is active, or when [Accelerated Database Recovery (ADR)](https://learn.microsoft.com/sql/relational-databases/accelerated-database-recovery-concepts) is enabled, every row in the database internally contains a transaction identifier.
25+
26+
The TID is stored on disk in the additional 14 bytes that are associated with each row when features such as RCSI or ADR are enabled.
27+
28+
Every transaction that modifies a row tags that row with its own TID, so each row in the database is labeled with the last TID that modified it.
29+
30+
### Contents
31+
32+
[About this sample](#about-this-sample)<br/>
33+
[Before you begin](#before-you-begin)<br/>
34+
[Run this sample](#run-this-sample)<br/>
35+
[Sample Details](#sample-details)<br/>
36+
[Disclaimers](#disclaimers)<br/>
37+
[Related links](#related-links)<br/>
38+
39+
<a name=about-this-sample></a>
40+
## About this sample
41+
42+
- **Applies to:** SQL Server 2025 (or higher), Azure SQL Database
43+
- **Key features:** Optimized Locking
44+
- **Workload:** No workload related to this sample
45+
- **Programming Language:** T-SQL
46+
- **Authors:** [Sergio Govoni](https://www.linkedin.com/in/sgovoni/) | [Microsoft MVP Profile](https://mvp.microsoft.com/mvp/profile/c7b770c0-3c9a-e411-93f2-9cb65495d3c4) | [Blog](https://segovoni.medium.com/) | [GitHub](https://github.com/segovoni) | [X](https://twitter.com/segovoni)
47+
48+
<a name=before-you-begin></a>
49+
## Before you begin
50+
51+
To run this sample, you need the following prerequisites.
52+
53+
**Software prerequisites:**
54+
55+
1. SQL Server 2025 (or higher) or Azure SQL Database
56+
57+
<a name=run-this-sample></a>
58+
## Run this sample
59+
60+
### Setup code
61+
62+
1. Download [create-configure-optimizedlocking-db.sql](sql-scripts/create-configure-optimizedlocking-db.sql) T-SQL script from sql-scripts folder
63+
2. Verify that a database named OptimizedLocking does not already exist in your SQL Server instance
64+
3. Execute create-configure-optimizedlocking-db.sql script on your SQL Server instance
65+
4. Run the commands described in the sample details section
66+
67+
<a name=sample-details></a>
68+
## Sample Details
69+
70+
Let's consider the table dbo.TelemetryPacket, with the schema defined in the following T-SQL code snippet.
71+
72+
```sql
73+
USE [OptimizedLocking]
74+
GO
75+
76+
CREATE TABLE dbo.TelemetryPacket
77+
(
78+
PacketID INT IDENTITY(1, 1)
79+
,Device CHAR(8000) DEFAULT ('Something')
80+
);
81+
GO
82+
```
83+
84+
The table schema is designed so that each row occupies exactly one data page.
85+
86+
Insert three rows with default values into the dbo.TelemetryPacket table. Note that this is done in a single transaction.
87+
88+
Before committing the transaction, we query the [sys.dm_tran_locks](https://learn.microsoft.com/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql) DMV, which exposes the TID locks as a new resource type = `XACT`.
89+
90+
```sql
91+
BEGIN TRANSACTION;
92+
93+
INSERT INTO dbo.TelemetryPacket DEFAULT VALUES;
94+
INSERT INTO dbo.TelemetryPacket DEFAULT VALUES;
95+
INSERT INTO dbo.TelemetryPacket DEFAULT VALUES;
96+
97+
SELECT
98+
l.resource_description
99+
,l.resource_associated_entity_id
100+
,l.resource_lock_partition
101+
,l.request_mode
102+
,l.request_type
103+
,l.request_status
104+
,l.request_owner_type
105+
FROM
106+
sys.dm_tran_locks AS l
107+
WHERE
108+
(l.request_session_id = @@SPID)
109+
AND (l.resource_type = 'XACT');
110+
111+
COMMIT;
112+
```
113+
114+
The resource_description column, in this example, reports the `XACT` value equal to `10:1147:0`.
115+
116+
TID `1147` represents the identifier of the transaction that inserted the rows and it will be stored in the row data page if the transaction is confirmed. Every subsequent change to the rows will update the TID.
117+
118+
Now let's make a change on the row identified by the PacketID value 2 and before confirming the transaction let's repeat again the query on the DMV.
119+
120+
```sql
121+
BEGIN TRANSACTION;
122+
123+
UPDATE
124+
t
125+
SET
126+
t.Device = 'Something updated'
127+
FROM
128+
dbo.TelemetryPacket AS t
129+
WHERE
130+
t.PacketID = 2;
131+
132+
SELECT
133+
l.resource_description
134+
,l.resource_associated_entity_id
135+
,l.resource_lock_partition
136+
,l.request_mode
137+
,l.request_type
138+
,l.request_status
139+
,l.request_owner_type
140+
FROM
141+
sys.dm_tran_locks AS l
142+
WHERE
143+
(l.request_session_id = @@SPID)
144+
AND (l.resource_type = 'XACT');
145+
146+
COMMIT;
147+
```
148+
149+
Even for the `UPDATE` command, the resource_description column displays the TID of the transaction that is modifying the row. If the transaction is confirmed, the TID will be stored in the data page of the row itself.
150+
151+
<a name=disclaimers></a>
152+
## Disclaimers
153+
154+
The code included in this sample is not intended to be a set of best practices on how to build scalable enterprise grade applications. This is beyond the scope of this sample.
155+
156+
<a name=related-links></a>
157+
## Related Links
158+
159+
- [Optimized locking](https://learn.microsoft.com/sql/relational-databases/performance/optimized-locking)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
------------------------------------------------------------------------
2+
-- Run this script on a SQL Server 2025 instance (or higher) to --
3+
-- create a database named OptimizedLocking if it doesn't exist --
4+
------------------------------------------------------------------------
5+
6+
USE [master];
7+
GO
8+
9+
CREATE DATABASE [OptimizedLocking];
10+
GO
11+
12+
ALTER DATABASE [OptimizedLocking] SET COMPATIBILITY_LEVEL = 170;
13+
ALTER DATABASE [OptimizedLocking] SET RECOVERY SIMPLE;
14+
ALTER DATABASE [OptimizedLocking] SET PAGE_VERIFY CHECKSUM;
15+
ALTER DATABASE [OptimizedLocking] SET ACCELERATED_DATABASE_RECOVERY = ON;
16+
ALTER DATABASE [OptimizedLocking] SET READ_COMMITTED_SNAPSHOT ON;
17+
ALTER DATABASE [OptimizedLocking] SET OPTIMIZED_LOCKING = ON;
18+
GO
19+
20+
USE [OptimizedLocking]
21+
GO
22+
23+
IF NOT EXISTS (
24+
SELECT
25+
[name]
26+
FROM
27+
sys.filegroups
28+
WHERE
29+
(is_default = 1)
30+
AND ([name] = N'PRIMARY')
31+
)
32+
BEGIN
33+
ALTER DATABASE [OptimizedLocking] MODIFY FILEGROUP [PRIMARY] DEFAULT;
34+
END;
35+
36+
SELECT
37+
[name] AS DatabaseName
38+
,is_accelerated_database_recovery_on AS [ADR Enabled]
39+
,is_read_committed_snapshot_on AS [RCSI Enabled]
40+
,is_optimized_locking_on AS [Optimized Locking Enabled]
41+
FROM
42+
sys.databases
43+
WHERE
44+
[name] = N'OptimizedLocking';
45+
46+
PRINT 'OptimizedLocking database created and configured successfully.';

samples/features/readme.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ In-Memory OLTP can significantly improve performance of transaction processing i
88

99
Master Data Services (MDS) is the SQL Server solution for master data management. Master data management (MDM) enables you organization to discover and define non-transactional lists of data, and compile maintainable, reliable master lists.
1010

11+
[Optimized Locking](optimized-locking)
12+
13+
Optimized Locking provides an improved transaction locking mechanism that reduces lock memory consumption and increases concurrency for workloads with high transaction volumes. Available in Azure SQL and SQL Server 2025 or higher, it uses Transaction ID (TID) locking and Lock After Qualification (LAQ) to minimize lock escalation and blocking.
14+
1115
[R Services](r-services)
1216

1317
SQL Server R Services (in SQL Server 2016 and above) brings R processing close to the data, allowing more scalable and more efficient predictive analytics using R in-database.
@@ -36,7 +40,4 @@ The SQL Server Management Objects (SMO) Framework is a set of objects designed f
3640

3741
[Reporting Services (SSRS)](reporting-services)
3842

39-
Reporting Services provides reporting capabilities for your organziation. Reporting Services can be integrated with SharePoint Server or used as a standalone service.
40-
41-
42-
43+
Reporting Services provides reporting capabilities for your organization. Reporting Services can be integrated with SharePoint Server or used as a standalone service.

0 commit comments

Comments
 (0)