feat: add DynamoDB transactional storage provider - #9616
Conversation
|
We are a team working on an unreleased project from one of South Korea's largest game development companies. I'd appreciate that if the core team could review the code. |
|
I noticed that the transaction in DynamoDB is quite slow compared to individual The comment here describes that it doesn't need to operate atomically.
|
4ae88c1 to
1ef18cd
Compare
bacb550 to
c7c68bf
Compare
c7c68bf to
9405794
Compare
9405794 to
abab9cb
Compare
There was a problem hiding this comment.
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.DynamoDBprovider 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.Testproject 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
|
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. |
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
e8c8ff5 to
ba472d2
Compare

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