Skip to content

feat: add DynamoDB transactional storage provider - #9616

Merged
ReubenBond merged 23 commits into
dotnet:mainfrom
scalalang2:dynamodb-transactional-storage
Aug 7, 2026
Merged

feat: add DynamoDB transactional storage provider#9616
ReubenBond merged 23 commits into
dotnet:mainfrom
scalalang2:dynamodb-transactional-storage

Conversation

@scalalang2

@scalalang2 scalalang2 commented Jul 18, 2025

Copy link
Copy Markdown
Contributor
Microsoft Reviewers: Open in CodeFlow

Background

Currently users can use distributed transaction in DynamoDB by using StateStorageBridge, but it aggregates all pending state into a single entry, Since DynamoDB limits the size of each entry upto 400 KB. It's not applicable for larger transactions. the data must be split into multiple entires, similar to the method used with Orleans.Transactions.AzureStorage

resolve #9150

@scalalang2 scalalang2 changed the title [Feature] [WIP] DynamoDB Transactional Storage Provider [Feature] DynamoDB Transactional Storage Provider Jul 19, 2025
@scalalang2

Copy link
Copy Markdown
Contributor Author

We are a team working on an unreleased project from one of South Korea's largest game development companies.
This provider has functioned properly during both internal testing and a pre-release test on Steam.

I'd appreciate that if the core team could review the code.

@scalalang2

Copy link
Copy Markdown
Contributor Author

I noticed that the transaction in DynamoDB is quite slow compared to individual DeleteItem, PutItem and UpdateItem.
Can I replace the the transactional operation to individual calls? @ReubenBond

The comment here describes that it doesn't need to operate atomically.

assemble all storage operations into a single batch
these operations must commit in sequence, but not necessarily atomically
so we can split this up if needed

image

@scalalang2
scalalang2 force-pushed the dynamodb-transactional-storage branch 2 times, most recently from 4ae88c1 to 1ef18cd Compare July 22, 2025 05:48
@ReubenBond
ReubenBond force-pushed the dynamodb-transactional-storage branch 3 times, most recently from bacb550 to c7c68bf Compare November 24, 2025 16:12
@ReubenBond
ReubenBond force-pushed the dynamodb-transactional-storage branch from c7c68bf to 9405794 Compare July 31, 2026 22:31
@ReubenBond
ReubenBond requested a review from Copilot August 1, 2026 00:35
@ReubenBond
ReubenBond force-pushed the dynamodb-transactional-storage branch from 9405794 to abab9cb Compare August 1, 2026 00:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an Orleans transactional state storage provider backed by AWS DynamoDB, aiming to support larger distributed transactions by splitting pending state across multiple DynamoDB items (avoiding the 400KB item-size limit) and introducing a dedicated DynamoDB transactions test suite.

Changes:

  • Added a new Microsoft.Orleans.Transactions.DynamoDB provider with DynamoDB-backed transactional state storage implementation and hosting registration APIs.
  • Extended the shared DynamoDB storage wrapper to support DynamoDB transactional write requests.
  • Added a new Orleans.Transactions.DynamoDB.Test project plus TestKit fault-injection wiring to validate transactional behavior and recovery.
Show a summary per file
File Description
test/Transactions/Orleans.Transactions.DynamoDB.Test/TransactionScopeTests.cs Adds scoped-transaction test runner coverage for DynamoDB.
test/Transactions/Orleans.Transactions.DynamoDB.Test/TransactionRecoveryTests.cs Adds recovery-after-silo-failure coverage using DynamoDB clustering.
test/Transactions/Orleans.Transactions.DynamoDB.Test/TransactionConcurrencyTests.cs Adds concurrency test runner coverage for DynamoDB.
test/Transactions/Orleans.Transactions.DynamoDB.Test/TocGoldenPathTests.cs Adds TOC golden-path coverage for DynamoDB.
test/Transactions/Orleans.Transactions.DynamoDB.Test/TocFaultTransactionTests.cs Adds TOC fault-path coverage for DynamoDB.
test/Transactions/Orleans.Transactions.DynamoDB.Test/TestFixture.cs Provides cluster fixture wiring for DynamoDB transactional storage and fault injection.
test/Transactions/Orleans.Transactions.DynamoDB.Test/SkewedClockGoldenPathTransactionTests.cs Adds skewed-clock golden-path coverage for DynamoDB.
test/Transactions/Orleans.Transactions.DynamoDB.Test/Orleans.Transactions.DynamoDB.Test.csproj Introduces new DynamoDB transactions test project and references.
test/Transactions/Orleans.Transactions.DynamoDB.Test/GrainFaultTests.cs Adds grain-fault scenario coverage for DynamoDB transactions.
test/Transactions/Orleans.Transactions.DynamoDB.Test/GoldenPathTests.cs Adds golden-path scenario coverage for DynamoDB transactions.
test/Transactions/Orleans.Transactions.DynamoDB.Test/FaultInjection/RandomInjection/ConsistencyFaultInjectionTests.cs Adds random fault-injection consistency coverage for DynamoDB.
test/Transactions/Orleans.Transactions.DynamoDB.Test/FaultInjection/ControlledInjection/TransactionFaultInjectionTests.cs Adds controlled fault-injection coverage for DynamoDB.
test/Transactions/Orleans.Transactions.DynamoDB.Test/DynamoDBTransactionalStateStorageTests.cs Adds direct transactional state storage test runner for DynamoDB implementation.
test/Transactions/Orleans.Transactions.DynamoDB.Test/ConsistencyTests.cs Adds consistency coverage for DynamoDB transactions.
test/Transactions/Orleans.Transactions.DynamoDB.Test/ConsistencySkewedClockTests.cs Adds skewed-clock consistency coverage for DynamoDB transactions.
test/Transactions/Orleans.Transactions.DynamoDB.Test/AssemblyInfo.cs Configures xUnit parallelism behavior for the new test project.
src/Orleans.Transactions.TestKit.Base/Orleans.Transactions.TestKit.Base.csproj Adds reference to the new DynamoDB transactions provider for TestKit.Base.
src/Orleans.Transactions.TestKit.Base/FaultInjection/ControlledInjection/TransactionFaultInjectionServiceCollectionExtensions.cs Adds fault-injection registration path for DynamoDB transactional storage.
src/Orleans.Transactions.TestKit.Base/FaultInjection/ControlledInjection/HostingExtensions.cs Adds ISiloBuilder extension for DynamoDB fault-injection storage registration.
src/Orleans.Transactions.TestKit.Base/FaultInjection/ControlledInjection/FaultInjectionDynamoDBTransactionStateStorage.cs Adds fault-injection wrapper/factory around DynamoDB transactional state storage.
src/AWS/Shared/Storage/DynamoDBStorage.cs Makes DynamoDBStorage public and adds a TransactWriteItems-based write API.
src/AWS/Shared/Storage/DynamoDBClientOptions.cs Adds TRANSACTIONS_DYNAMODB namespace selection for shared options.
src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/StateEntity.cs Adds DynamoDB item model for transaction state rows.
src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/KeyEntity.cs Adds DynamoDB item model for the “key” row (commit pointer/metadata).
src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/DynamoDBTransactionalStateStorageFactory.cs Adds transactional storage factory and lifecycle initialization for DynamoDB.
src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/DynamoDBTransactionalStateStorage.cs Adds DynamoDB transactional state storage implementation.
src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/DynamoDBTransactionalStateConstants.cs Defines DynamoDB attribute/alias constants for transactional storage.
src/AWS/Orleans.Transactions.DynamoDB/README.md Adds package README for DynamoDB transactions provider.
src/AWS/Orleans.Transactions.DynamoDB/Orleans.Transactions.DynamoDB.csproj Introduces new DynamoDB transactions provider project and shared-source links.
src/AWS/Orleans.Transactions.DynamoDB/Options/DynamoDBTransactionalStorageOptions.cs Adds options + validator for transactional DynamoDB storage.
src/AWS/Orleans.Transactions.DynamoDB/Hosting/DynamoDBTransactionSiloBuilderExtensions.cs Adds ISiloBuilder extensions to register DynamoDB transactional storage.
src/AWS/Orleans.Transactions.DynamoDB/Hosting/DynamoDBTransactionServiceCollectionExtensions.cs Adds IServiceCollection registration for DynamoDB transactional storage.
src/AWS/Orleans.Persistence.DynamoDB/Options/DynamoDBStorageOptions.cs Touches persistence options file as part of DynamoDB options work (per diff).
Orleans.slnx Adds the new provider and test projects to the solution.

Copilot's findings

Suppressed comments (3)

src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/StateEntity.cs:76

  • These non-nullable properties are not initialized (and SetState assigns null to a non-nullable byte[]), which will produce nullable warnings-as-errors in the main build. Either initialize them or make them nullable (and update SetState accordingly).
    public string PartitionKey { get; set; } = null!;

    public string RowKey { get; set; } = null!;

src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/KeyEntity.cs:43

  • PartitionKey/RowKey are non-nullable but not initialized (and the Dictionary-based ctor only sets PartitionKey when the attribute exists), which will raise nullable warnings-as-errors. Provide defaults so the type is always in a valid state.
    public string PartitionKey { get; set; } = null!;

    public string RowKey { get; set; }

src/AWS/Orleans.Transactions.DynamoDB/Options/DynamoDBTransactionalStorageOptions.cs:98

  • These configuration exceptions refer to "DynamoDBGrainStorage", but this validator is for the transactional storage provider. The current message is misleading when users are troubleshooting configuration.
            if (string.IsNullOrWhiteSpace(this.options.TableName))
                throw new OrleansConfigurationException(
                    $"Configuration for DynamoDBGrainStorage {this.name} is invalid. {nameof(this.options.TableName)} is not valid.");

            if (this.options.UseProvisionedThroughput)
            {
                if (this.options.ReadCapacityUnits == 0)
                    throw new OrleansConfigurationException(
                        $"Configuration for DynamoDBGrainStorage {this.name} is invalid. {nameof(this.options.ReadCapacityUnits)} is not valid.");

                if (this.options.WriteCapacityUnits == 0)
                    throw new OrleansConfigurationException(
                        $"Configuration for DynamoDBGrainStorage {this.name} is invalid. {nameof(this.options.WriteCapacityUnits)} is not valid.");
  • Files reviewed: 33/34 changed files
  • Comments generated: 9

Comment thread src/AWS/Shared/Storage/DynamoDBStorage.cs
Comment thread src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/StateEntity.cs Outdated
Comment thread src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/KeyEntity.cs Outdated
@ReubenBond

Copy link
Copy Markdown
Member

Regarding replacing transactional batches with individual writes: the overall Store operation can be split into sequential chunks, but each chunk still needs to atomically include its state mutations and a conditional key/ETag update. Otherwise a stale or failed writer can leave state rows inconsistent with the committed metadata. The current implementation keeps TransactWriteItems, limits each chunk to 99 data operations plus the key synchronizer, and advances the ETag between chunks.

@ReubenBond ReubenBond changed the title [Feature] DynamoDB Transactional Storage Provider feat: add DynamoDB transactional storage provider Aug 7, 2026
ReubenBond and others added 8 commits August 7, 2026 15:55
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 30769b52-5dfb-4bc6-9cb9-6bf16f79c3f4
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 30769b52-5dfb-4bc6-9cb9-6bf16f79c3f4
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 30769b52-5dfb-4bc6-9cb9-6bf16f79c3f4
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 30769b52-5dfb-4bc6-9cb9-6bf16f79c3f4
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 30769b52-5dfb-4bc6-9cb9-6bf16f79c3f4
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 30769b52-5dfb-4bc6-9cb9-6bf16f79c3f4
@ReubenBond
ReubenBond force-pushed the dynamodb-transactional-storage branch from e8c8ff5 to ba472d2 Compare August 7, 2026 22:55
@ReubenBond
ReubenBond merged commit 8d2fd2d into dotnet:main Aug 7, 2026
66 of 67 checks passed
This was referenced Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Orleans.Transactions.DynamoDB.

3 participants