Skip to content

Commit 426832f

Browse files
committed
RavenDB-25154 - Document TrackingMode session option and TrackAllEntities feature
- Update SessionOptions table in opening-a-session to include TrackingMode parameter - Rewrite disable-tracking page to cover TrackingMode enum (NoTracking, TrackAllEntities, Default) - Add TrackAllEntities section explaining automatic change tracking for all loaded entities - Update main disable-tracking page title and description to reflect broader tracking configuration scope
1 parent 9004ec8 commit 426832f

File tree

3 files changed

+127
-25
lines changed

3 files changed

+127
-25
lines changed

docs/client-api/session/configuration/content/_how-to-disable-tracking-csharp.mdx

Lines changed: 123 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,123 @@ import CodeBlock from '@theme/CodeBlock';
55

66
<Admonition type="note" title="">
77

8-
* By default, each session tracks changes to all entities it has either stored, loaded, or queried for.
9-
All changes are then persisted when `SaveChanges` is called.
8+
* By default, each session tracks changes to all entities it has either stored, loaded, or queried for.
9+
All changes are then persisted when `SaveChanges` is called.
1010

11-
* Tracking can be disabled at various scopes:
12-
for a specific entity, for entities returned by a query, for all entities in a session, or globally using conventions.
11+
* The session's tracking behavior can be configured using the `TrackingMode` option in `SessionOptions`.
12+
13+
* Tracking can also be disabled at more granular scopes:
14+
for a specific entity, for entities returned by a query, or globally using conventions.
1315

1416
* In this article:
15-
* [Disable tracking changes for a specific entity](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#disable-tracking-changes-for-a-specific-entity)
17+
* [Tracking mode](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#tracking-mode)
18+
* [Track all entities](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#track-all-entities)
1619
* [Disable tracking all entities in session](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#disable-tracking-all-entities-in-session)
20+
* [Disable tracking changes for a specific entity](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#disable-tracking-changes-for-a-specific-entity)
1721
* [Disable tracking query results](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#disable-tracking-query-results)
1822
* [Customize tracking in conventions](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#customize-tracking-in-conventions)
1923
* [Using 'Include' in a NoTracking session will throw](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#using-)
2024

2125
</Admonition>
26+
## Tracking mode
27+
28+
* Use the `TrackingMode` option in `SessionOptions` to configure entity tracking behavior for the session.
29+
30+
| Value | Description |
31+
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
32+
| **Default** | Standard tracking. The session tracks changes only to entities that are stored, loaded, or queried. Modified entities are persisted when `SaveChanges` is called. |
33+
| **NoTracking** | Tracking is disabled. Entities are not tracked. `Store` is not available. Each `Load` or `Query` call creates new entity instances. Equivalent to the deprecated `SessionOptions.NoTracking = true`. |
34+
| **TrackAllEntities** | Extended tracking. In addition to the default behavior, the session records the change vectors of **all** entities it encounters (loaded, queried, or included). On `SaveChanges`, these change vectors are sent to the server, which verifies that none of the tracked entities were modified by another session. A `ConcurrencyException` is thrown if a conflict is detected. |
35+
36+
**Syntax**
37+
38+
<TabItem value="syntax_tracking_mode" label="syntax_tracking_mode">
39+
<CodeBlock language="csharp">
40+
{`public enum TrackingMode
41+
{
42+
Default,
43+
NoTracking,
44+
TrackAllEntities
45+
}`}
46+
</CodeBlock>
47+
</TabItem>
48+
49+
<Admonition type="warning" title="Deprecation notice">
50+
51+
The `SessionOptions.NoTracking` boolean property is deprecated and will be removed in a future major version.
52+
Use `SessionOptions.TrackingMode` instead. Setting both `NoTracking` and `TrackingMode` on the same `SessionOptions` object will throw an `InvalidOperationException`.
53+
54+
</Admonition>
55+
56+
<Admonition type="info" title="Limitation">
57+
58+
`TrackingMode.TrackAllEntities` is not compatible with `TransactionMode.ClusterWide`.
59+
Setting both will throw an `InvalidOperationException`.
60+
61+
</Admonition>
62+
63+
64+
65+
## Track all entities
66+
67+
* When `TrackingMode` is set to `TrackAllEntities`, the session tracks the change vectors of all entities it encounters -
68+
not only those that are modified.
69+
* On `SaveChanges`, the session sends the tracked change vectors to the server as part of the batch operation.
70+
* The server validates that none of the tracked entities were modified by another session since they were loaded.
71+
* If a tracked entity was modified externally, a `ConcurrencyException` is thrown and none of the changes in the batch are persisted.
72+
* This provides **session-wide optimistic concurrency** - ensuring that the data you read has not changed by the time you save.
73+
74+
**Example**
75+
76+
<Tabs groupId='languageSyntax'>
77+
<TabItem value="Sync" label="Sync">
78+
<CodeBlock language="csharp">
79+
{`using (IDocumentSession session = store.OpenSession(new SessionOptions
80+
{
81+
// Enable tracking for all entities
82+
TrackingMode = TrackingMode.TrackAllEntities
83+
}))
84+
{
85+
// Load two entities - the session records both change vectors
86+
Employee employee1 = session.Load<Employee>("employees/1-A");
87+
Employee employee2 = session.Load<Employee>("employees/2-A");
88+
89+
// Modify only employee2
90+
employee2.FirstName = "New Name";
91+
92+
// On SaveChanges, the server verifies that BOTH employee1 and employee2
93+
// have not been modified by another session since they were loaded.
94+
// If either was modified externally, a ConcurrencyException is thrown.
95+
session.SaveChanges();
96+
}`}
97+
</CodeBlock>
98+
</TabItem>
99+
<TabItem value="Async" label="Async">
100+
<CodeBlock language="csharp">
101+
{`using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions
102+
{
103+
// Enable tracking for all entities
104+
TrackingMode = TrackingMode.TrackAllEntities
105+
}))
106+
{
107+
// Load two entities - the session records both change vectors
108+
Employee employee1 = await asyncSession.LoadAsync<Employee>("employees/1-A");
109+
Employee employee2 = await asyncSession.LoadAsync<Employee>("employees/2-A");
110+
111+
// Modify only employee2
112+
employee2.FirstName = "New Name";
113+
114+
// On SaveChanges, the server verifies that BOTH employee1 and employee2
115+
// have not been modified by another session since they were loaded.
116+
// If either was modified externally, a ConcurrencyException is thrown.
117+
await asyncSession.SaveChangesAsync();
118+
}`}
119+
</CodeBlock>
120+
</TabItem>
121+
</Tabs>
122+
123+
124+
22125
## Disable tracking changes for a specific entity
23126

24127
* You can prevent the session from persisting changes made to a specific entity by using `IgnoreChangesFor`.
@@ -79,50 +182,48 @@ await asyncSession.SaveChangesAsync();
79182

80183
## Disable tracking all entities in session
81184

82-
* Tracking can be disabled for all entities in the session's options.
83-
* When tracking is disabled for the session:
185+
* Tracking can be disabled for all entities in the session's options.
186+
* When tracking is disabled for the session:
84187
* Method `Store` will Not be available (an exception will be thrown if used).
85-
* Calling `Load` or `Query` will generate a call to the server and create new entities instances.
188+
* Calling `Load` or `Query` will generate a call to the server and create new entities instances.
86189

87190
<Tabs groupId='languageSyntax'>
88191
<TabItem value="Sync" label="Sync">
89192
<CodeBlock language="csharp">
90193
{`using (IDocumentSession session = store.OpenSession(new SessionOptions
91194
{
92195
// Disable tracking for all entities in the session's options
93-
NoTracking = true
196+
TrackingMode = TrackingMode.NoTracking
94197
}))
95198
{
96199
// Load any entity, it will Not be tracked by the session
97200
Employee employee1 = session.Load<Employee>("employees/1-A");
98-
201+
99202
// Loading again from same document will result in a new entity instance
100203
Employee employee2 = session.Load<Employee>("employees/1-A");
101-
204+
102205
// Entities instances are not the same
103206
Assert.NotEqual(employee1, employee2);
104-
}
105-
`}
207+
}`}
106208
</CodeBlock>
107209
</TabItem>
108210
<TabItem value="Async" label="Async">
109211
<CodeBlock language="csharp">
110212
{`using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions
111213
{
112214
// Disable tracking for all entities in the session's options
113-
NoTracking = true
215+
TrackingMode = TrackingMode.NoTracking
114216
}))
115217
{
116218
// Load any entity, it will Not be tracked by the session
117219
Employee employee1 = await asyncSession.LoadAsync<Employee>("employees/1-A");
118-
220+
119221
// Loading again from same document will result in a new entity instance
120222
Employee employee2 = await asyncSession.LoadAsync<Employee>("employees/1-A");
121223
122224
// Entities instances are not the same
123225
Assert.NotEqual(employee1, employee2);
124-
}
125-
`}
226+
}`}
126227
</CodeBlock>
127228
</TabItem>
128229
</Tabs>
@@ -308,7 +409,7 @@ await asyncSession.SaveChangesAsync();
308409
{`using (IDocumentSession session = store.OpenSession(new SessionOptions
309410
{
310411
// Working with a non-tracking session
311-
NoTracking = true
412+
TrackingMode = TrackingMode.NoTracking
312413
}))
313414
{
314415
try
@@ -317,7 +418,7 @@ await asyncSession.SaveChangesAsync();
317418
Product product1 = session
318419
.Include<Product>(x => x.Supplier)
319420
.Load<Product>("products/1-A");
320-
421+
321422
// The same applies when using the builder syntax:
322423
Product product2 = session.Load<Product>("products/1-A",
323424
builder => builder.IncludeDocuments(product => product.Supplier));
@@ -335,7 +436,7 @@ await asyncSession.SaveChangesAsync();
335436
{`using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions
336437
{
337438
// Working with a non-tracking session
338-
NoTracking = true
439+
TrackingMode = TrackingMode.NoTracking
339440
}))
340441
{
341442
try
@@ -367,7 +468,7 @@ await asyncSession.SaveChangesAsync();
367468
{`using (IDocumentSession session = store.OpenSession(new SessionOptions
368469
{
369470
// Working with a non-tracking session
370-
NoTracking = true
471+
TrackingMode = TrackingMode.NoTracking
371472
}))
372473
{
373474
try
@@ -391,7 +492,7 @@ await asyncSession.SaveChangesAsync();
391492
{`using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions
392493
{
393494
// Working with a non-tracking session
394-
NoTracking = true
495+
TrackingMode = TrackingMode.NoTracking
395496
}))
396497
{
397498
try

docs/client-api/session/configuration/how-to-disable-tracking.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
2-
title: "Disable Entity Tracking"
3-
sidebar_label: Disable Tracking
2+
title: "Configure Entity Tracking"
3+
sidebar_label: Configure Tracking
44
sidebar_position: 5
55
supported_languages: ["csharp", "python", "php", "nodejs"]
66
see_also:

docs/client-api/session/content/_opening-a-session-csharp.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ IAsyncDocumentSession OpenAsyncSession(SessionOptions options);
7373
| Option | Type | Description | Default Value |
7474
|---------------------------------------------------------|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|
7575
| **Database** | `string` | The Session will operate on this database,<br/>overriding the Default Database. | `null` - the Session operates on the Default Database |
76-
| **NoTracking** | `bool` | `true` - The Session tracks changes made to all entities it loaded, stored, or queried for.<br/>`false` - Tracking will be turned off.<br/>Learn more in [Disable tracking](../../../client-api/session/configuration/how-to-disable-tracking.mdx) | `false` |
76+
| **TrackingMode** | `TrackingMode` | Configure the session's entity tracking behavior:<br/>`Default` - Standard tracking (track only modified entities).<br/>`NoTracking` - Disable tracking for all entities.<br/>`TrackAllEntities` - Track change vectors of all loaded entities; on `SaveChanges`, the server verifies none were modified externally, throwing a `ConcurrencyException` if they were.<br/>Learn more in [Configure tracking](../../../client-api/session/configuration/how-to-disable-tracking.mdx) | `Default` |
77+
| **NoTracking** _(deprecated)_ | `bool` | _Deprecated. Use `TrackingMode` instead._<br/>`true` - Tracking will be turned off.<br/>`false` - Default tracking behavior.<br/>Learn more in [Configure tracking](../../../client-api/session/configuration/how-to-disable-tracking.mdx) | `false` |
7778
| **NoCaching** | `bool` | `true` - Server responses will Not be cached.<br/>`false` - The Session caches the server responses.<br/>Learn more in [Disable caching](../../../client-api/session/configuration/how-to-disable-caching.mdx) | `false` |
7879
| **RequestExecutor** | `RequestExecutor` | ( _Advanced option_ ) <br/>The request executor the Session should use. | `null` - the default request executor is used |
7980
| **TransactionMode** | `TransactionMode` | Specify the Session's transaction mode<br/>`SingleNode` / `ClusterWide`<br/>Learn more in [Cluster-wide vs. Single-node](../../../client-api/session/cluster-transaction/overview.mdx#cluster-wide-transaction-vs-single-node-transaction) | `SingleNode` |

0 commit comments

Comments
 (0)