Wednesday, August 16, 2023

Azure Table 'batch' (transaction) operations

To bulk insert rows in the old Azure Table Storage API you would create a TableBatchOperation class and fill it with TableOperations, then call ExecuteBatchAsync. The batch could contain different operations, but bulk inserts were my most common need.

The batch related classes do not exist in the new Table API, and finding the replacement code was a dreadful chore. I didn't know the expression batch had been replaced with transaction, so my searches for "batch" produced endless useless old results and discussions. After searching until my fingers bled I stumbled across a hint that batch processing as was now transaction processing. Useful search results now started to arrive, but it took more time to finally find some definitive sample code that actually worked. The best summary page I found was here:

azure-sdk-for-net Transactional Batches

My sanity check code in LINQPad looks like this:

async Task Main()
{
	var tsclient = new TableServiceClient("YOUR STORAGE CONNECT STRING");
	var tclient = tsclient.GetTableClient("TestTable1");
	await tclient.CreateIfNotExistsAsync().Dump();
	var trans = new List<TableTransactionAction>>();
	var rows = Enumerable.Range(1, 10).Select(i => new MockRow()
	{
		Id = i,
		Name = $"Name for {i}"
	} ).ToArray();
	trans.AddRange(rows.Select(r => new TableTransactionAction(TableTransactionActionType.Add, r)));
	await tclient.SubmitTransactionAsync(trans).Dump();
}

class MockRow : ITableEntity
{
	public string PartitionKey { get; set; } = "P1";
	public string RowKey { get; set; } = Guid.NewGuid().ToString("N");
	public DateTimeOffset? Timestamp { get; set; }
	public ETag ETag { get; set; }
	public int Id { get; set; }
	public string Name { get; set; }
}

Transaction success returns status 202 and a list of sub-responses with status 204. I deliberately caused an error while inserting a transaction of 5 rows, by setting the second RowKey with invalid characters. As advertised, no rows are inserted and a TableTransactionFailedException is thrown with a detailed message like this:

2:The 'RowKey' parameter of value 'Bad\Key' is out of range.
RequestId:c10901e2-e002-009a-7aba-cf9069000000
Time:2023-08-15T20:55:37.4158811Z
 The index of the entity that caused the error can be found in FailedTransactionActionIndex.
Status: 400 (Bad Request)
ErrorCode: OutOfRangeInput
Additional Information:
FailedEntity: 2

No comments:

Post a Comment