Current section
Files
Jump to
Current section
Files
lib/aerospike/txn.ex
defmodule Aerospike.Txn do
@moduledoc """
Transaction handle for multi-record transactions (MRT).
An `Aerospike.Txn` is a lightweight, immutable data structure that identifies a
transaction in progress. Create one with `new/0` or `new/1`, then pass it as the
`txn:` option to any CRUD operation that participates in the transaction.
## Creating a transaction
txn = Aerospike.Txn.new()
Aerospike.put(:conn, key1, %{"score" => 10}, txn: txn)
Aerospike.put(:conn, key2, %{"score" => 20}, txn: txn)
Aerospike.commit(:conn, txn)
You can set a timeout (in milliseconds). A timeout of `0` means the server applies
its default transaction timeout:
txn = Aerospike.Txn.new(timeout: 5_000)
## State management
Transaction state — tracked reads, tracked writes, commit/abort status — lives in an
ETS table managed by the connection, **not** in this struct. The struct is a read-only
handle that identifies the transaction by its `id`.
Passing the same `%Txn{}` to multiple concurrent processes is undefined behavior:
the ETS state is shared, and concurrent mutation is not protected by any lock.
## Constraints
- All operations within a single transaction must target the **same namespace**.
- A transaction supports at most 4096 write keys.
- Scans and queries cannot participate in a transaction.
- Transactions require Aerospike Enterprise Edition with strong-consistency namespaces.
"""
# Full signed int64 range: -(2^63) to 2^63-1
@int64_min -9_223_372_036_854_775_808
# 2^64 — the number of distinct values in the signed int64 range
@int64_range 18_446_744_073_709_551_616
@enforce_keys [:id, :timeout]
defstruct [:id, :timeout]
@type t :: %__MODULE__{
id: integer(),
timeout: non_neg_integer()
}
@doc """
Creates a new transaction handle with a random ID and zero timeout.
The `id` is a uniformly random signed 64-bit integer. A `timeout` of `0`
instructs the server to apply its configured default transaction timeout.
## Examples
iex> txn = Aerospike.Txn.new()
iex> is_integer(txn.id)
true
iex> txn.timeout
0
"""
@spec new() :: t()
def new do
%__MODULE__{id: random_id(), timeout: 0}
end
@doc """
Creates a new transaction handle with the given options.
## Options
- `:timeout` — transaction timeout in milliseconds (default: `0`, meaning server default)
## Examples
iex> txn = Aerospike.Txn.new(timeout: 5_000)
iex> txn.timeout
5_000
"""
@spec new(keyword()) :: t()
def new(opts) when is_list(opts) do
timeout = Keyword.get(opts, :timeout, 0)
%__MODULE__{id: random_id(), timeout: timeout}
end
# Generates a uniformly random signed int64.
# :rand.uniform(N) returns an integer in 1..N; subtracting 1 shifts it to 0..N-1.
# Adding @int64_min maps [0, 2^64-1] → [-2^63, 2^63-1].
defp random_id do
@int64_min + :rand.uniform(@int64_range) - 1
end
end