Leveraging full ACID transaction in Cosmos DB using Transaction Batch support in .NET SQL SDK
Tags: transactionbatch, cosmosdb, azure
Published: 2020-01-20 21:26:52

[Originally posted at msajid.cloud](https://www.msajid.cloud/2020/01/20/leveraging-full-acid-transaction-in-cosmos-db-using-transactionbatch-support-in-net-sql-sdk/)
In this post you will learn
 * [What is TransactionBatch?](#part-1)
 * [Sample scenario and demo](#part-2)
 * [TransactionalBatch or Stored procedure?](#part-3)
 * [Limitations](#part-4)
 * [Conclusion](#part-5)



With the release of .NET SQL SDK version 3.4, The Cosmos DB team has released support for TransactionalBatch, With TransactionalBatch, it is now possible to save multiple documents in a single batch operation. 

<a name="part-1"></a>
#What is TransactionBatch? 
Documents in the batch will either all succeed atomically, or all be rolled back together. 
Yes, you guessed it right, it is a full ACID transaction support within the same logical partition key, straight from the SDK. Previously you had to write and call server-side stored procedures written in JavaScript to achieve the same functionality. 

<a name="part-2"></a>
#Sample scenario and demo
Banks use [Event sourcing](https://www.msajid.cloud/2018/02/16/event-sourcing-as-an-evolutionary-architectural-pattern/) to store events (bank transactions). These events are immutable and banks maintain a complete log of changes (transactions) as Events in an Event store. Some possible events in a bank scenario could be AccountCreated, DepositPerformed, and WithdrawPerformed, etc. 

When you visit a bank for opening a new bank account, you might have a requirement to deposit a minimum amount in order to activate your account. Think of it as two Events, one for creating an account and the second one is performing a sufficient deposit. If you save two documents via separate calls to the Cosmos DB one for the account creation and second for a deposit, you risk the second call to fail and you end up in a situation where you have an invalid account. You want to make sure both Events either saved successfully or none of them gets saved. In such situations, you might want to use TransactionBatch support to create a batch with both AccountCreated and DepositPerformed events and then commit the transaction. See the following code sample 

{% gist https://gist.github.com/msajid/322a2c8d86bca6dc194ef7046bc202fe %}


<a name="part-3"></a>
#TransactionBatch or Stored procedure?
You might ask what’s wrong with writing a server-side stored procedure. Nothing wrong as such, but there are many reasons to prefer TransactionalBatch over authoring stored procedures

##Better testability
Since it is just like any other code you write, you can use your favorite mocking framework or other familiar techniques for testing it.

##The preferred choice of language
At the time of writing, this feature is available only in .NET SDK but Cosmos DB product team is planning to release this support for many other languages like Node, Python, and Java 

##Easier version control
With Server-Side stored procedures, you always had to update your stored procedure before deploying your new code, and imagine if things don’t work out as you expected, how painful a rollback could be, Similarly In the world where CI/CD it is crucial to have everything as Code. 

##Better performance
According to Microsoft, a 30% reduction in latency has been experienced when compared to Stored procedures for equal operations. Other than comparing it with Stored procedures, Saving documents as a batch reduces the number of round trips as well.
 
##Content serialization flexibility
With TransactionBatch support directly in your code, you have complete control of the way you want to serialize your object.

<a name="part-4"></a>
#Limitations 
 * Maximum payload size is 2MB
 * Maximum number of operations are 100 per TransactionalBatch

<a name="part-5"></a>
#Conclusion
If there is anything difficult in a distributed database, that is support for the transaction. Cosmos DB product team has done a tremendous job by providing this feature directly in the SDK. Transactions are a very useful feature when you need an all or nothing behavior.  Please let me know in the comments what situations you think this feature would be useful.

[Check Matias Quaranta blog for more details](https://devblogs.microsoft.com/cosmosdb/introducing-transactionalbatch-in-the-net-sdk/)