{"id":375,"date":"2020-01-07T11:24:43","date_gmt":"2020-01-07T19:24:43","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/cosmosdb\/?p=375"},"modified":"2020-05-04T06:15:17","modified_gmt":"2020-05-04T13:15:17","slug":"introducing-transactionalbatch-in-the-net-sdk","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/introducing-transactionalbatch-in-the-net-sdk\/","title":{"rendered":"Introducing TransactionalBatch in the Azure Cosmos DB .NET SDK"},"content":{"rendered":"<p>Recently <a href=\"http:\/\/devblogs.microsoft.com\/cosmosdb\/introducing-bulk-support-in-the-net-sdk\/\">we talked about the new Bulk support<\/a> introduced in the .NET SQL SDK, but along with it, another great feature was also released: support for TransactionalBatch.<\/p>\n<h2>Wait, Bulk? Batch? What\u2019s the difference?<\/h2>\n<p>While Bulk describes scenarios that require a high degree of throughput to process a high volume of point operations, these operations can succeed or fail independently.<\/p>\n<p>TransactionalBatch describes a <strong>group of point operations that need to either succeed or fail<\/strong>. If all operations, in the order that are described in the TransactionalBatch, succeed, the transaction is committed. If any operation fails, the entire transaction is rolled back.<\/p>\n<h2>So, what is a transaction for Cosmos DB?<\/h2>\n<p>A transaction in a typical database can be defined as a sequence of operations performed as a single logical unit of work. Each transaction provides ACID (Atomicity, Consistency, Isolation, Durability) property guarantees.<\/p>\n<ul>\n<li><strong>Atomicity<\/strong> guarantees that all the operations done inside a transaction are treated as a single unit, and either all of them are committed or none of them are.<\/li>\n<li><strong>Consistency<\/strong> makes sure that the data is always in a valid state across transactions.<\/li>\n<li><strong>Isolation<\/strong> guarantees that no two transactions interfere with each other \u2013 many commercial systems provide multiple isolation levels that can be used based on the application needs.<\/li>\n<li><strong>Durability<\/strong> ensures that any change that is committed in a database will always be present.<\/li>\n<\/ul>\n<p>Azure Cosmos DB supports <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/database-transactions-optimistic-concurrency\">full ACID compliant transactions with snapshot isolation<\/a> for operations within the same <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/partition-data\">logical partition key<\/a>.<\/p>\n<h2>Got it. How do I create a TransactionalBatch now?<\/h2>\n<p>Creating a TransactionalBatch is a very descriptive operation, you basically start from a Container instance and call <strong>CreateTransactionalBatch<\/strong>:<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/b691d11b2f40dd30deadee050389f095<\/p>\n<p>And when you are ready, just call <strong>ExecuteAsync:<\/strong><\/p>\n<p>https:\/\/gist.github.com\/ealsur\/b552864f64ffadddfae5e0274e47fcaf<\/p>\n<p>When the response comes back, you need to examine if it\u2019s a success or not, and extract the results:<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/70955bfdeff1b935d827f67d08ac65d0<\/p>\n<p>In case of a <strong>failure<\/strong>, the failing operation will have the <strong>StatusCode<\/strong> of its corresponding error, while all the other operations will have a <a href=\"https:\/\/tools.ietf.org\/html\/rfc4918#section-11.4\">424 StatusCode<\/a> (Failed Dependency). So, it\u2019s quite easy to identify the cause of the transaction failure.<\/p>\n<p>https:\/\/gist.github.com\/ealsur\/3d18f0cbc6258e8f27565a8581790e45<\/p>\n<h2>How is that TransactionalBatch executed?<\/h2>\n<p>When ExecuteAsync is called, all operations in the TransactionalBatch are grouped, <strong>serialized into a single payload<\/strong>, and sent as a <strong>single request<\/strong> to the Azure Cosmos DB service.<\/p>\n<p>The service receives the request and executes all operations within a <strong>transactional scope<\/strong>, and returns a response using the same serialization protocol. This response is either a success, or a failure, and contains all the <strong>individual operation responses<\/strong> internally.<\/p>\n<p>The SDK exposes the response for you to verify the result and, optionally, extract each of the internal operation results. Quite simple.<\/p>\n<h2>Why would I use TransactionalBatch?<\/h2>\n<p>It is known that Azure Cosmos DB supports Stored Procedures, which also <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/stored-procedures-triggers-udfs#scope-of-a-transaction\">provide transactional scope<\/a> on its operations, but why would you use TransactionalBatch vs Stored Procedures?<\/p>\n<ul>\n<li>Pick your own <strong>language<\/strong> \u2013 TransactionalBatch is supported on the SDK and language you work with already, while Stored Procedures need to be written in Javascript.<\/li>\n<li>Code <strong>versioning<\/strong> \u2013 Versioning application code and onboarding it on your CI\/CD pipeline is much more natural than orchestrating the update of a Stored Procedure and making sure the rollover happens at the right time. It also makes rolling back changes much easier.<\/li>\n<li><strong>Performance<\/strong> \u2013 We have seen reduction in latency for equivalent operations of up to 30% when comparing them with a Stored Procedure execution.<\/li>\n<li><strong>Content serialization <\/strong>\u2013 Each operation within a TransactionalBatch can leverage custom serialization options for its payload.<\/li>\n<\/ul>\n<h2>Are there any known limits?<\/h2>\n<p>Currently, there are three known limits:<\/p>\n<ul>\n<li>As per the <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/concepts-limits#per-request-limits\">Azure Cosmos DB request size limit<\/a>, the size of the TransactionalBatch payload cannot exceed 2MB, and the maximum execution time is 5 seconds.<\/li>\n<li>There is a current limit of 100 operations per TransactionalBatch to make sure the performance is as expected and within SLAs.<\/li>\n<\/ul>\n<h2>Next steps<\/h2>\n<p>If you want to try out TransactionalBatch, you can follow our <a href=\"https:\/\/github.com\/Azure\/azure-cosmos-dotnet-v3\/tree\/master\/Microsoft.Azure.Cosmos.Samples\/Usage\/TransactionalBatch\">sample<\/a>. Please share any feedback on our <a href=\"https:\/\/github.com\/Azure\/azure-cosmos-dotnet-v3\/issues\">official Github repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to use the Azure Cosmos DB .NET SDK TransactionalBatch support to leverage transactional scope on groups of operations that need to atomically commit as a unit<\/p>\n","protected":false},"author":9477,"featured_media":61,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[12,14,19],"tags":[331,330,333,332],"class_list":["post-375","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcements","category-core-sql-api","category-tips-and-tricks","tag-batch","tag-bulk","tag-transaction","tag-transactionalbatch"],"acf":[],"blog_post_summary":"<p>Learn how to use the Azure Cosmos DB .NET SDK TransactionalBatch support to leverage transactional scope on groups of operations that need to atomically commit as a unit<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/375","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/9477"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=375"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/375\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/61"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=375"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=375"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=375"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}