Search code examples
c#azuretransactionsazure-table-storagerace-condition

In Azure Table Storage, how to do "get or insert" atomically?


I am developing a C# Azure application using C#, .NET 5.0 and Microsoft.Azure.Cosmos.Table version 1.0.8. I want to do the following:

  1. Look in the table storage for a row/entity with a particular partition key and row key.
  2. If it exists, then return the entity.
  3. If it doesn't exist, then create one, store it in the table storage and return it.

I want to do this atomically to avoid race conditions (i.e., if two threads try to do this simultaneously, I want to guarantee that they return the same value and that only one entity gets stored in the table storage).

TableOperation has InsertOrMerge and InsertOrReplace, but they don't seem to be what I want. Both of them, as far as I can see, will prefer the last value written, which I don't want. I want it to keep the first value that gets written (so that all concurrent threads will return the same value).

How can I do this?

Thanks in advance!


Solution

  • AFAIK, it is not possible to accomplish what you're trying to do atomically. You will need to perform 2 operations.

    Your first operation will be an Insert operation (instead of InsertOrMerge or InsertOrReplace). If the entity does not exist, then it will be created and the newly created entity will be returned.

    If the entity exists in the table, your insert operation will fail with a Conflict (409) error. Your application code will need to handle this error and read the entity from the table and return that entity.