AshCommanded.Commanded.Transaction (AshCommanded v0.1.0)
View SourceTransaction support for command execution in AshCommanded.
This module provides functionality for wrapping command execution inside database transactions, ensuring atomicity of operations across multiple resources and commands.
Transactions can be used in two ways:
- Automatically based on command configuration in the DSL
- Manually by wrapping command execution in a transaction block
Features
- Supports single command transactions
- Supports multi-command transactions
- Integrates with Ash Repository transactions
- Handles rollback on error
- Provides transaction options (timeout, isolation level)
Summary
Functions
Executes multiple commands in a single transaction.
Executes a function within a transaction.
Checks whether a repository supports transactions.
Types
@type transaction_function() :: (-> any())
Function that will be executed within a transaction
@type transaction_options() :: [ timeout: pos_integer(), isolation_level: :read_committed | :repeatable_read | :serializable ]
Options for transaction execution
Functions
@spec execute_commands(module(), [map()], transaction_options()) :: {:ok, map()} | {:error, any(), any(), %{required(atom()) => any()}}
Executes multiple commands in a single transaction.
Parameters
repo
- The repository to use for the transactioncommands
- List of commands to execute, each with resource and actionopts
- Transaction options
Command Structure
Each command in the list should be a map with these keys:
:command
- The command struct to execute:resource
- The resource module:action
- The action name (atom):opts
- (Optional) Command-specific options
Returns
{:ok, result_map}
- Map of results from all commands{:error, failed_operation, failed_value, changes_so_far}
- Error information
Examples
iex> AshCommanded.Commanded.Transaction.execute_commands(MyApp.Repo, [
...> %{command: create_user_cmd, resource: MyApp.User, action: :create},
...> %{command: create_profile_cmd, resource: MyApp.Profile, action: :create}
...> ])
{:ok, %{create_user: %MyApp.User{...}, create_profile: %MyApp.Profile{...}}}
@spec run(module(), transaction_function(), transaction_options()) :: {:ok, any()} | {:error, any()}
Executes a function within a transaction.
Parameters
repo
- The repository to use for the transactionfun
- The function to execute inside the transactionopts
- Transaction options
Options
:timeout
- Transaction timeout in milliseconds:isolation_level
- Transaction isolation level (:read_committed
,:repeatable_read
, or:serializable
)
Returns
{:ok, result}
- The result of the function, if the transaction succeeded{:error, reason}
- The error that caused the transaction to roll back
Examples
iex> AshCommanded.Commanded.Transaction.run(MyApp.Repo, fn ->
...> # Execute commands or actions
...> AshCommanded.Commanded.CommandActionMapper.map_to_action(command, resource, action)
...> end)
{:ok, %MyApp.User{id: "123", name: "John"}}
Checks whether a repository supports transactions.
Parameters
repo
- The repository to check
Returns
true
- If the repository supports transactionsfalse
- If the repository does not support transactions
Examples
iex> AshCommanded.Commanded.Transaction.supports_transactions?(MyApp.Repo)
true
iex> AshCommanded.Commanded.Transaction.supports_transactions?(MyApp.InMemoryRepo)
false