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
title: How to manage concurrent writes to resources
2
+
title: Manage concurrent writes
3
3
titleSuffix: Azure AI Search
4
4
description: Use optimistic concurrency to avoid mid-air collisions on updates or deletes to Azure AI Search indexes, indexers, data sources.
5
5
6
6
manager: nitinme
7
7
author: HeidiSteen
8
8
ms.author: heidist
9
9
ms.service: cognitive-search
10
-
ms.topic: conceptual
11
-
ms.date: 01/26/2021
10
+
ms.topic: how-to
11
+
ms.date: 04/23/2024
12
12
ms.custom:
13
13
- devx-track-csharp
14
14
- ignite-2023
15
15
---
16
-
# How to manage concurrency in Azure AI Search
17
16
18
-
When managing Azure AI Search resources such as indexes and data sources, it's important to update resources safely, especially if resources are accessed concurrently by different components of your application. When two clients concurrently update a resource without coordination, race conditions are possible. To prevent this, Azure AI Search offers an *optimistic concurrency model*. There are no locks on a resource. Instead, there is an ETag for every resource that identifies the resource version so that you can formulate requests that avoid accidental overwrites.
17
+
# Manage concurrency in Azure AI Search
19
18
20
-
> [!Tip]
21
-
> Conceptual code in a [sample C# solution](https://github.com/Azure-Samples/search-dotnet-getting-started/tree/master/DotNetETagsExplainer) explains how concurrency control works in Azure AI Search. The code creates conditions that invoke concurrency control. Reading the [code fragment below](#samplecode) might be sufficient for most developers, but if you want to run it, edit appsettings.json to add the service name and an admin api-key. Given a service URL of `http://myservice.search.windows.net`, the service name is `myservice`.
19
+
When managing Azure AI Search resources such as indexes and data sources, it's important to update resources safely, especially if resources are accessed concurrently by different components of your application. When two clients concurrently update a resource without coordination, race conditions are possible. To prevent this, Azure AI Search uses an *optimistic concurrency model*. There are no locks on a resource. Instead, there's an ETag for every resource that identifies the resource version so that you can formulate requests that avoid accidental overwrites.
22
20
23
21
## How it works
24
22
@@ -28,147 +26,125 @@ All resources have an [*entity tag (ETag)*](https://en.wikipedia.org/wiki/HTTP_E
28
26
29
27
+ The REST API uses an [ETag](/rest/api/searchservice/common-http-request-and-response-headers-used-in-azure-search) on the request header.
30
28
31
-
+ The .NET SDK sets the ETag through an accessCondition object, setting the [If-Match | If-Match-None header](/rest/api/searchservice/common-http-request-and-response-headers-used-in-azure-search) on the resource. Objects that use ETags, such as [SynonymMap.ETag](/dotnet/api/azure.search.documents.indexes.models.synonymmap.etag) and [SearchIndex.ETag](/dotnet/api/azure.search.documents.indexes.models.searchindex.etag), have an accessCondition object.
29
+
+ The Azure SDK for .NET sets the ETag through an accessCondition object, setting the [If-Match | If-Match-None header](/rest/api/searchservice/common-http-request-and-response-headers-used-in-azure-search) on the resource. Objects that use ETags, such as [SynonymMap.ETag](/dotnet/api/azure.search.documents.indexes.models.synonymmap.etag) and [SearchIndex.ETag](/dotnet/api/azure.search.documents.indexes.models.searchindex.etag), have an accessCondition object.
32
30
33
-
Every time you update a resource, its ETag changes automatically. When you implement concurrency management, all you're doing is putting a precondition on the update request that requires the remote resource to have the same ETag as the copy of the resource that you modified on the client. If a concurrent process has changed the remote resource already, the ETag will not match the precondition and the request will fail with HTTP 412. If you're using the .NET SDK, this manifests as a `CloudException` where the `IsAccessConditionFailed()` extension method returns true.
31
+
Every time you update a resource, its ETag changes automatically. When you implement concurrency management, all you're doing is putting a precondition on the update request that requires the remote resource to have the same ETag as the copy of the resource that you modified on the client. If another process changes the remote resource, the ETag doesn't match the precondition and the request fails with HTTP 412. If you're using the .NET SDK, this failure manifests as an exception where the `IsAccessConditionFailed()` extension method returns true.
34
32
35
33
> [!Note]
36
-
> There is only one mechanism for concurrency. It's always used regardless of which API is used for resource updates.
34
+
> There is only one mechanism for concurrency. It's always used regardless of which API or SDK is used for resource updates.
37
35
38
-
<aname="samplecode"></a>
39
36
## Use cases and sample code
40
37
41
-
The following code demonstrates accessCondition checks for key update operations:
42
-
43
-
+ Fail an update if the resource no longer exists
44
-
+ Fail an update if the resource version changes
45
-
46
-
### Sample code from [DotNetETagsExplainer program](https://github.com/Azure-Samples/search-dotnet-getting-started/tree/master/DotNetETagsExplainer)
38
+
The following code demonstrates optimistic concurrency for an update operation. It fails the second update because the object's ETag is changed by a previous update. More specifically, when the ETag in the request header no longer matches the ETag of the object, the search service return a status 400 bad request message, and the update fails.
47
39
48
40
```csharp
49
-
classProgram
41
+
usingAzure;
42
+
usingAzure.Search.Documents;
43
+
usingAzure.Search.Documents.Indexes;
44
+
usingAzure.Search.Documents.Indexes.Models;
45
+
usingSystem;
46
+
usingSystem.Net;
47
+
usingSystem.Threading.Tasks;
48
+
49
+
namespaceAzureSearch.SDKHowTo
50
50
{
51
-
// This sample shows how ETags work by performing conditional updates and deletes
A design pattern for implementing optimistic concurrency should include a loop that retries the access condition check, a test for the access condition, and optionally retrieves an updated resource before attempting to re-apply the changes.
145
+
A design pattern for implementing optimistic concurrency should include a loop that retries the access condition check, a test for the access condition, and optionally retrieves an updated resource before attempting to reapply the changes.
170
146
171
-
This code snippet illustrates the addition of a synonymMap to an index that already exists. This code is from the [Synonym C# example for Azure AI Search](https://github.com/Azure-Samples/search-dotnet-getting-started/tree/v10/DotNetHowToSynonyms).
147
+
This code snippet illustrates the addition of a synonymMap to an index that already exists.
172
148
173
149
The snippet gets the "hotels" index, checks the object version on an update operation, throws an exception if the condition fails, and then retries the operation (up to three times), starting with index retrieval from the server to get the latest version.
@@ -205,15 +181,8 @@ private static Index AddSynonymMapsToFields(Index index)
205
181
}
206
182
```
207
183
208
-
## Next steps
209
-
210
-
Try modifying other samples to exercise ETags or AccessCondition objects.
211
-
212
-
+[search-dotnet-getting-started on GitHub](https://github.com/Azure-Samples/search-dotnet-getting-started). This repository includes the "DotNetEtagsExplainer" project.
213
-
214
-
+[azure-search-dotnet-samples on GitHub](https://github.com/Azure-Samples/azure-search-dotnet-samples) contains additional C# samples.
0 commit comments