-
Notifications
You must be signed in to change notification settings - Fork 2k
Add documentation for cosmos db provider transactional batches #5100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: live
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
--- | ||
title: Azure Cosmos DB Provider - Atomicity of SaveChanges - EF Core | ||
description: Explains the atomicity of SaveChanges within the Entity Framework Core Azure Cosmos DB provider as compared to other providers | ||
author: JoasE | ||
ms.date: 09/10/2025 | ||
uid: core/providers/cosmos/savechanges-atomicity | ||
--- | ||
# EF Core Azure Cosmos DB Provider Atomicity of SaveChanges | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd suggest putting this content in a general Cosmos page called "Save data" (just like the top-level docs category we already have); if we have other SaveChanges-related content, it seems like it would go into the same page rather than having a whole separate page just for atomicity, etc. In any case, the title here (and above in the front matter) should be aligned with the way it's done in other pages. |
||
|
||
Azure Cosmos DB does not support transactions in the relational database sense. That is, there is no concept of a single atomic transaction spanning arbitrary operations across containers or partitions. This is a common limitation of document databases, where the focus is on scalability and availability rather than strict transactional semantics. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The word feels a bit too hard, given that just below we discuss transactional batches which do provide relational-like transactional guarantees (albeit with some restrictions). |
||
|
||
Instead of transactions, Azure Cosmos DB provides support for [transactional batches](/azure/cosmos-db/nosql/transactional-batch). A transactional batch allows up to 100 operations to be executed together as a batch within a single partition. Atomicity is guaranteed within a single batch: if any operation fails, the entire batch is rolled back and none of its changes are applied. However, once a batch is written, it cannot be rolled back or deferred, and atomicity cannot be enforced across multiple batches. | ||
|
||
The EF Core Azure Cosmos DB provider leverages transactional batches whenever possible, providing a best-effort approximation of atomicity when saving changes. | ||
|
||
## How EF Core saves changes in batches | ||
|
||
When SaveChanges or SaveChangesAsync is called, the provider groups pending changes into transactional batches. Each batch contains up to 100 entries, grouped by container and partition key. These batches are then executed sequentially. If a batch fails, execution stops immediately and no subsequent batches are attempted. Any batches that were successfully committed before the failure remain saved. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to describe the default behavior (Auto), without mentioning that this behavior can be changed. I'd simply merge this doc section with the one below - both deal with the same thing. |
||
|
||
> [!WARNING] | ||
> Azure Cosmos DB does not allow document writes with [pre- or post-triggers](/azure/cosmos-db/nosql/stored-procedures-triggers-udfs#triggers) to be part of a transactional batch. Because of this, any entities configured with triggers are executed separately and before any transactional batches. This can affect ordering and consistency in mixed scenarios. | ||
## Controlling batching behavior | ||
|
||
The batching behavior of the EF Core Azure Cosmos DB provider is controlled by the <xref:Microsoft.EntityFrameworkCore.Storage.IDatabase.AutoTransactionBehavior> property. This setting allows developers to trade off between performance, consistency guarantees, and failure behavior depending on the application’s needs. | ||
|
||
* **Auto** (default) – Entries are grouped into transactional batches as described above. This generally provides good performance for writing to multiple entities within the same partition with a best-effort approximation of atomicity. | ||
* **Never** – All entries are written individually, in the exact order they were tracked. This avoids batching and can be slower, especially for large numbers of entries. | ||
* **Always** – Requires that all changes can be executed as a single atomic operation. If any entries cannot be included in a batch (for example, due to partitioning, exceeding 100 items, or there are multiple changed entries including one with triggers), the provider will throw an exception. | ||
|
||
```csharp | ||
using var context = new BlogsContext(); | ||
context.Database.AutoTransactionBehavior = AutoTransactionBehavior.Always; | ||
context.AddRange(Enumerable.Range(0, 101).Select(i => new Post())); | ||
await context.SaveChangesAsync(); // Throws InvalidOperationException | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.