TransactionalSession¶
- class aerospike_sdk.aio.transactional_session.TransactionalSession[source]¶
Bases:
TransactionalSessionBase,SessionAsync context manager that groups operations into a multi-record transaction.
Subclasses
Session, so every session API (query,upsert,insert,batch, …) works unchanged insideasync with; builders capture the activeTxnviacurrent_transactionand thread it onto every policy they hand to the PNC — the user never touches a policy.On clean exit the transaction is committed; if an exception propagates out of the block the transaction is aborted. Explicit
commit()andabort()are also available for manual control. Either finalizes the session: a later operation on it raisesTransactionErrorwithResultCode.TXN_ALREADY_COMMITTEDorResultCode.TXN_ALREADY_ABORTEDinstead of running outside the transaction.Example:
async with client.create_session().transaction() as tx: await tx.upsert(accounts.id("A")).bin("balance").set_to(100).execute() await tx.upsert(accounts.id("B")).bin("balance").set_to(200).execute() # Auto-committed on clean exit; auto-aborted on exception.
- __init__(client, behavior=None)[source]¶
Create a transactional session; prefer
Session.transaction().- Parameters:
Note
Application code should not construct
TransactionalSessiondirectly; callSession.transaction()orClient.transaction()instead.
- async get(key, bins=None)[source]¶
Direct single-key point read — returns
Recordor raises.Bypasses the builder chain (
session.query(key).execute()) and theRecordStreamwrapper: oneawaitreaches the underlying client and the resultingRecordis returned unwrapped. Use when you have a single key and want minimum per-op overhead; usequery()when you need filters, projections, or streaming.- Parameters:
- Return type:
Record- Returns:
The
Recordforkey.- Raises:
AerospikeError – Server or client errors (including
KEY_NOT_FOUND_ERROR) are raised as the SDK exception type for the failure, without being wrapped in aRecordResult.
Example:
users = DataSet.of("test", "users") rec = await session.get(users.id(1)) name = rec.bins["name"]
See also
query(): Builder-based reads for projections, streams, and secondary-index queries.put(): Direct single-key upsert.
- async put(key, bins)[source]¶
Direct single-key upsert — returns
Noneor raises.Bypasses the builder chain (
session.upsert(key).put(...).execute()) and theRecordStreamwrapper: oneawaitreaches the underlying client. Use when you have a single key and want minimum per-op overhead; useupsert()when you need atomic multi-op semantics, TTL overrides, generation checks, durable delete, or filter expressions.- Parameters:
- Return type:
- Returns:
Noneon success.- Raises:
AerospikeError – Server or client errors are raised as the SDK exception type for the failure.
Example:
users = DataSet.of("test", "users") await session.put(users.id(1), {"name": "Tim", "age": 30})
See also
upsert(): Builder-based writes with full feature set.get(): Direct single-key point read.
- async get_many(keys, bins=None)[source]¶
Direct point reads for a window of keys — one await, one result list.
Client-side fusion of independent single-record reads: one call submits the whole window and one completion delivers all results, so per-op submission and wakeup overhead is amortized across the window. These are NOT a server batch request — each key remains an independent wire op (use
query()with a key list for wire batching).- Parameters:
- Return type:
List[Union[Record,AerospikeError]]- Returns:
A list the same length as
keys. Each slot is theRecordfor that key, or theAerospikeErrorinstance (not raised) for that key — check withisinstance(slot, AerospikeError). One failed key never fails its window-mates.Records are handed back raw rather than wrapped in
RecordResult: a wrapper per slot would cost one allocation per key, which is the per-op cost this API exists to amortize. The asymmetry with the builder surface is deliberate.- Raises:
AerospikeError – When the whole-window submission fails (for example, the client was closed); per-key failures land in result slots instead.
Example:
users = DataSet.of("test", "users") records = await session.get_many([users.id(i) for i in range(16)]) found = [r for r in records if not isinstance(r, AerospikeError)]
See also
get(): Single-key point read.put_many(): Window counterpart for writes.
- async put_many(keys, bins)[source]¶
Direct upserts of one payload to a window of keys — one await.
Write counterpart of
get_many(): thebinspayload is converted once and written to every key in the window as independent wire ops with client-side fused submission/completion.- Parameters:
- Returns:
Nonefor each success, or theAerospikeErrorinstance (not raised) for that key. Slots are bare rather thanRecordResultfor the same allocation reason asget_many().- Return type:
- Raises:
AerospikeError – When the whole-window submission fails; per-key failures land in result slots instead.
Example:
users = DataSet.of("test", "users") outcomes = await session.put_many( [users.id(i) for i in range(16)], {"active": True}) errors = [e for e in outcomes if e is not None]
See also
put(): Single-key upsert.get_many(): Window counterpart for reads.
- async do_in_transaction(operation, *, max_attempts=None, sleep_between_retries=None)[source]¶
Join this transaction instead of starting a nested one.
A transaction cannot contain another transaction, so the useful reading of a nested call is “run this as part of the transaction I am already in”. Opening a second one instead would silently split the caller’s work across two transactions that commit independently – losing the atomicity the outer call was written to get.
The outermost call owns the commit and the retrying, so the retry arguments do not apply here and are accepted only to keep the signature substitutable.
- Parameters:
- Return type:
- Returns:
Whatever
operationreturns.- Raises:
RuntimeError – If this session’s transaction is no longer active.
Example:
async def transfer(tx): await tx.upsert(src).put({"balance": 90}).execute() # Joins the transaction already in progress. return await tx.do_in_transaction(audit) await session.do_in_transaction(transfer)
See also
aerospike_sdk.aio.session.Session.do_in_transaction(): Theoutermost entry point, which does open a transaction.
- async commit()[source]¶
Commit the transaction and return the server-reported status.
ROLL_FORWARD_CLOSE_ABANDONEDis still success: the writes are durable and only monitor cleanup was left to the server. An abandoned roll-forward raises instead — those writes are not yet visible.A commit that fails in doubt — the roll-forward mark may or may not have reached the server — leaves the transaction open and retryable, and calling this again is the only way to resolve it:
abort()is refused from that point, because rolling back could discard writes the server is committing. Every other commit failure finalizes the session as before.- Raises:
RuntimeError – If the transaction was never started.
TransactionError – With
ResultCode.TXN_ALREADY_ABORTEDif the transaction was aborted.CommitError – The roll-forward was abandoned, or another commit stage failed.
- Return type:
- Returns:
COMMITTED,ALREADY_COMMITTEDon a repeat call, or anotherTxnStatusthe server reported.
See also
abort(): Undo the transaction instead of committing.
- async abort()[source]¶
Abort the transaction and return the server-reported status.
Refused after a commit failed in doubt: the server may be rolling the transaction forward, and rolling back would discard those writes. The transaction stays open in that case, so
commit()can still be retried.- Raises:
RuntimeError – If the transaction was never started.
TransactionError – With
ResultCode.TXN_ALREADY_COMMITTEDif the transaction was committed.AerospikeError – If the abort was refused because a commit already failed in doubt, or the roll-back itself failed.
- Return type:
- Returns:
ABORTED,ALREADY_ABORTEDon a repeat call, or anotherTxnStatusthe server reported.
See also
commit(): Persist the transaction instead of aborting.
- property active: bool¶
Truewhen a transaction has been started and not yet finalized.- Returns:
Whether a transaction is currently active on this session.
Example:
with session.transaction() as tx: assert tx.active
- execute_udf(*keys)¶
Run a registered server-side UDF on one or more keys (foreground).
Chain
function(package, name)(package is the registered module name without.lua), optionalpassing(*args)for Lua parameters, optionalwherefor a filter expression, thenawait ...execute()to obtain aRecordStream. Multiple keys use a batch UDF; results preserve per-key order where applicable.- Parameters:
*keys (
Key) – One or moreKeytargets in the same namespace and set.- Return type:
- Returns:
UdfFunctionBuilder— callfunctionnext.- Raises:
ValueError – If no keys are given.
RuntimeError – If the client is not connected.
Example:
users = DataSet.of("test", "users") stream = await ( session.execute_udf(users.id("a")) .function("my_module", "my_fn") .passing("binName", 42) .execute() ) value = await stream.first_udf_result()
See also
query(): Read bins without UDF.background_task(): Dataset-scoped background UDF.
- property txn: Txn¶
Return the active
Txn.- Raises:
RuntimeError – If the session has not been entered (no active txn).
- Returns:
The active
Txn.
Example:
with session.transaction() as tx: assert tx.txn is not None