diff --git a/docs/client-api/session/configuration/content/_how-to-disable-tracking-csharp.mdx b/docs/client-api/session/configuration/content/_how-to-disable-tracking-csharp.mdx index 20b9c2afeb..4a01866f25 100644 --- a/docs/client-api/session/configuration/content/_how-to-disable-tracking-csharp.mdx +++ b/docs/client-api/session/configuration/content/_how-to-disable-tracking-csharp.mdx @@ -5,20 +5,123 @@ import CodeBlock from '@theme/CodeBlock'; -* By default, each session tracks changes to all entities it has either stored, loaded, or queried for. - All changes are then persisted when `SaveChanges` is called. +* By default, each session tracks changes to all entities it has either stored, loaded, or queried for. + All changes are then persisted when `SaveChanges` is called. -* Tracking can be disabled at various scopes: - for a specific entity, for entities returned by a query, for all entities in a session, or globally using conventions. +* The session's tracking behavior can be configured using the `TrackingMode` option in `SessionOptions`. + +* Tracking can also be disabled at more granular scopes: + for a specific entity, for entities returned by a query, or globally using conventions. * In this article: - * [Disable tracking changes for a specific entity](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#disable-tracking-changes-for-a-specific-entity) + * [Tracking mode](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#tracking-mode) + * [Track all entities](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#track-all-entities) * [Disable tracking all entities in session](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#disable-tracking-all-entities-in-session) + * [Disable tracking changes for a specific entity](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#disable-tracking-changes-for-a-specific-entity) * [Disable tracking query results](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#disable-tracking-query-results) * [Customize tracking in conventions](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#customize-tracking-in-conventions) * [Using 'Include' in a NoTracking session will throw](../../../../client-api/session/configuration/how-to-disable-tracking.mdx#using-) +## Tracking mode + +* Use the `TrackingMode` option in `SessionOptions` to configure entity tracking behavior for the session. + +| Value | Description | +|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Default** | Standard tracking. The session tracks changes only to entities that are stored, loaded, or queried. Modified entities are persisted when `SaveChanges` is called. | +| **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`. | +| **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. | + +**Syntax** + + + +{`public enum TrackingMode +{ + Default, + NoTracking, + TrackAllEntities +}`} + + + + + +The `SessionOptions.NoTracking` boolean property is deprecated and will be removed in a future major version. +Use `SessionOptions.TrackingMode` instead. Setting both `NoTracking` and `TrackingMode` on the same `SessionOptions` object will throw an `InvalidOperationException`. + + + + + +`TrackingMode.TrackAllEntities` is not compatible with `TransactionMode.ClusterWide`. +Setting both will throw an `InvalidOperationException`. + + + + + +## Track all entities + +* When `TrackingMode` is set to `TrackAllEntities`, the session tracks the change vectors of all entities it encounters - + not only those that are modified. +* On `SaveChanges`, the session sends the tracked change vectors to the server as part of the batch operation. +* The server validates that none of the tracked entities were modified by another session since they were loaded. +* If a tracked entity was modified externally, a `ConcurrencyException` is thrown and none of the changes in the batch are persisted. +* This provides **session-wide optimistic concurrency** - ensuring that the data you read has not changed by the time you save. + +**Example** + + + + +{`using (IDocumentSession session = store.OpenSession(new SessionOptions +{ + // Enable tracking for all entities + TrackingMode = TrackingMode.TrackAllEntities +})) +{ + // Load two entities - the session records both change vectors + Employee employee1 = session.Load("employees/1-A"); + Employee employee2 = session.Load("employees/2-A"); + + // Modify only employee2 + employee2.FirstName = "New Name"; + + // On SaveChanges, the server verifies that BOTH employee1 and employee2 + // have not been modified by another session since they were loaded. + // If either was modified externally, a ConcurrencyException is thrown. + session.SaveChanges(); +}`} + + + + +{`using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions +{ + // Enable tracking for all entities + TrackingMode = TrackingMode.TrackAllEntities +})) +{ + // Load two entities - the session records both change vectors + Employee employee1 = await asyncSession.LoadAsync("employees/1-A"); + Employee employee2 = await asyncSession.LoadAsync("employees/2-A"); + + // Modify only employee2 + employee2.FirstName = "New Name"; + + // On SaveChanges, the server verifies that BOTH employee1 and employee2 + // have not been modified by another session since they were loaded. + // If either was modified externally, a ConcurrencyException is thrown. + await asyncSession.SaveChangesAsync(); +}`} + + + + + + ## Disable tracking changes for a specific entity * You can prevent the session from persisting changes made to a specific entity by using `IgnoreChangesFor`. @@ -79,10 +182,10 @@ await asyncSession.SaveChangesAsync(); ## Disable tracking all entities in session -* Tracking can be disabled for all entities in the session's options. -* When tracking is disabled for the session: +* Tracking can be disabled for all entities in the session's options. +* When tracking is disabled for the session: * Method `Store` will Not be available (an exception will be thrown if used). - * Calling `Load` or `Query` will generate a call to the server and create new entities instances. + * Calling `Load` or `Query` will generate a call to the server and create new entities instances. @@ -90,19 +193,18 @@ await asyncSession.SaveChangesAsync(); {`using (IDocumentSession session = store.OpenSession(new SessionOptions { // Disable tracking for all entities in the session's options - NoTracking = true + TrackingMode = TrackingMode.NoTracking })) { // Load any entity, it will Not be tracked by the session Employee employee1 = session.Load("employees/1-A"); - + // Loading again from same document will result in a new entity instance Employee employee2 = session.Load("employees/1-A"); - + // Entities instances are not the same Assert.NotEqual(employee1, employee2); -} -`} +}`} @@ -110,19 +212,18 @@ await asyncSession.SaveChangesAsync(); {`using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions { // Disable tracking for all entities in the session's options - NoTracking = true + TrackingMode = TrackingMode.NoTracking })) { // Load any entity, it will Not be tracked by the session Employee employee1 = await asyncSession.LoadAsync("employees/1-A"); - + // Loading again from same document will result in a new entity instance Employee employee2 = await asyncSession.LoadAsync("employees/1-A"); // Entities instances are not the same Assert.NotEqual(employee1, employee2); -} -`} +}`} @@ -308,7 +409,7 @@ await asyncSession.SaveChangesAsync(); {`using (IDocumentSession session = store.OpenSession(new SessionOptions { // Working with a non-tracking session - NoTracking = true + TrackingMode = TrackingMode.NoTracking })) { try @@ -317,7 +418,7 @@ await asyncSession.SaveChangesAsync(); Product product1 = session .Include(x => x.Supplier) .Load("products/1-A"); - + // The same applies when using the builder syntax: Product product2 = session.Load("products/1-A", builder => builder.IncludeDocuments(product => product.Supplier)); @@ -335,7 +436,7 @@ await asyncSession.SaveChangesAsync(); {`using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions { // Working with a non-tracking session - NoTracking = true + TrackingMode = TrackingMode.NoTracking })) { try @@ -367,7 +468,7 @@ await asyncSession.SaveChangesAsync(); {`using (IDocumentSession session = store.OpenSession(new SessionOptions { // Working with a non-tracking session - NoTracking = true + TrackingMode = TrackingMode.NoTracking })) { try @@ -391,7 +492,7 @@ await asyncSession.SaveChangesAsync(); {`using (IAsyncDocumentSession asyncSession = store.OpenAsyncSession(new SessionOptions { // Working with a non-tracking session - NoTracking = true + TrackingMode = TrackingMode.NoTracking })) { try diff --git a/docs/client-api/session/configuration/how-to-disable-tracking.mdx b/docs/client-api/session/configuration/how-to-disable-tracking.mdx index 3d5eace4aa..5cb3796669 100644 --- a/docs/client-api/session/configuration/how-to-disable-tracking.mdx +++ b/docs/client-api/session/configuration/how-to-disable-tracking.mdx @@ -1,6 +1,6 @@ --- -title: "Disable Entity Tracking" -sidebar_label: Disable Tracking +title: "Configure Entity Tracking" +sidebar_label: Configure Tracking sidebar_position: 5 supported_languages: ["csharp", "python", "php", "nodejs"] see_also: diff --git a/docs/client-api/session/content/_opening-a-session-csharp.mdx b/docs/client-api/session/content/_opening-a-session-csharp.mdx index 7bd2c8bf84..2aef3c8b51 100644 --- a/docs/client-api/session/content/_opening-a-session-csharp.mdx +++ b/docs/client-api/session/content/_opening-a-session-csharp.mdx @@ -73,7 +73,8 @@ IAsyncDocumentSession OpenAsyncSession(SessionOptions options); | Option | Type | Description | Default Value | |---------------------------------------------------------|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------| | **Database** | `string` | The Session will operate on this database,
overriding the Default Database. | `null` - the Session operates on the Default Database | -| **NoTracking** | `bool` | `true` - The Session tracks changes made to all entities it loaded, stored, or queried for.
`false` - Tracking will be turned off.
Learn more in [Disable tracking](../../../client-api/session/configuration/how-to-disable-tracking.mdx) | `false` | +| **TrackingMode** | `TrackingMode` | Configure the session's entity tracking behavior:
`Default` - Standard tracking (track only modified entities).
`NoTracking` - Disable tracking for all entities.
`TrackAllEntities` - Track change vectors of all loaded entities; on `SaveChanges`, the server verifies none were modified externally, throwing a `ConcurrencyException` if they were.
Learn more in [Configure tracking](../../../client-api/session/configuration/how-to-disable-tracking.mdx) | `Default` | +| **NoTracking** _(deprecated)_ | `bool` | _Deprecated. Use `TrackingMode` instead._
`true` - Tracking will be turned off.
`false` - Default tracking behavior.
Learn more in [Configure tracking](../../../client-api/session/configuration/how-to-disable-tracking.mdx) | `false` | | **NoCaching** | `bool` | `true` - Server responses will Not be cached.
`false` - The Session caches the server responses.
Learn more in [Disable caching](../../../client-api/session/configuration/how-to-disable-caching.mdx) | `false` | | **RequestExecutor** | `RequestExecutor` | ( _Advanced option_ )
The request executor the Session should use. | `null` - the default request executor is used | | **TransactionMode** | `TransactionMode` | Specify the Session's transaction mode
`SingleNode` / `ClusterWide`
Learn more in [Cluster-wide vs. Single-node](../../../client-api/session/cluster-transaction/overview.mdx#cluster-wide-transaction-vs-single-node-transaction) | `SingleNode` |