pub async fn transaction_async<C: ConnectionLike + Clone, K: ToRedisArgs, T: FromRedisValue, F: FnMut(C, Pipeline) -> Fut, Fut: Future<Output = Result<Option<T>, RedisError>>>(
connection: C,
keys: &[K],
func: F,
) -> Result<T, RedisError>Expand description
Executes a Redis transaction asynchronously by automatically watching keys and running
a transaction loop until it succeeds. Similar to the synchronous transaction
function but for async execution.
The provided closure may be executed multiple times if the transaction fails due to
watched keys being modified between WATCH and EXEC. Any side effects in the closure
should account for possible multiple executions. The closure should return Ok(None) to indicate a transaction failure and to
retry (this will happen automatically if the last call in the closure is to run the transaction), or Err(err) to abort the
transaction with an error. A successful transaction should return Ok(Some(value)) with the desired result from the EXEC command.
§Examples
use redis::{AsyncCommands, RedisResult, pipe};
async fn increment(con: redis::aio::MultiplexedConnection) -> RedisResult<isize> {
let key = "my_counter";
redis::aio::transaction_async(con, &[key], |mut con, mut pipe| async move {
// Read the current value first
let val: isize = con.get(key).await?;
// Build the pipeline and execute it atomically (MULTI/EXEC are added automatically)
pipe.set(key, val + 1)
.ignore()
.get(key)
.query_async(&mut con)
.await
})
.await
}§Notes
- The closure may be executed multiple times if watched keys are modified by other
clients between
WATCHandEXEC; its side effects must be idempotent. - A successful
EXECautomatically discards allWATCHes, so no explicitUNWATCHis needed on the success path. - The transaction is automatically abandoned if the closure returns an error; an
explicit
UNWATCHis sent in that case to leave the connection in a clean state.
§Warning: Concurrent Transactions on Multiplexed Connections
When using a multiplexed connection (e.g. async connection types in this crate),
cloning shares the underlying channel. Running concurrent transactions on clones of
the same multiplexed connection could lead to unexpected behavior: the
WATCH/MULTI/EXEC sequence from one transaction may interleave with commands from
another. Ensure at most one transaction is active on a given multiplexed
connection at a time.
§Warning: Transactions on cluster connections
A cluster connection is a collection of multiple underlying connections to different
cluster nodes. Running a transaction on a cluster connection is only safe if all the
keys being watched and modified in the transaction are guaranteed to be on the same
cluster node, since Redis transactions cannot span multiple nodes. It is the caller’s
responsibility to ensure this condition is met when using transaction_async with a
cluster connection.
For more details on Redis transactions, see the Redis documentation