How to do transaction in asynchronous redis-rs

Hi, I am new to redis and redis-rs crate. I am trying to execute a transaction. However, I find no clue for this. No documentation or examples from the official redis-rs crate mention about this, I am pretty sure. Here's the minimal example of how to create an asynchronous redis connection:

let client = redis::Client::open("redis://127.0.0.1/").unwrap();
let con = client.get_tokio_connection().await.unwrap();

// What next..?

I know how to execute simple commands, like GET and SET. However, I am still trying to figure out how can I do transactions...

Here is an example redis-rs

see the transaction block or go through other examples I personally don't know much about transactions

1 Like

Hi, @lohargaurav00

I indeed already read the example you referred to, before posting this question. However, I am struggling when I got compiler error by passing redis::io::Connection as &mut con to the redis::transaction() function. I have no clue why this happens. It says the trait bound is not satisfied...

I've tried this:

async fn fetch_user_cache(app: &mut App) {
  let a = redis::transaction(&mut app.redis_conn, &[], |con, pipe| {
    pipe.query(con)
  }).unwrap();
}

I don't know much I'm new in the Rust community,

you can try executing a connection mut and executing a transaction at the same block.

I know examples and documentation of redis-rs not good

1 Like

I'm not familiar with the redis-rs crate so I can't help you at the high-level.

But someone may be able to at least tell you what the compiler error is about, if you share the whole error (copy the text from cargo build in a console into a code block).

Hi, @quinedot

Here's the full error from the cargo:

error[E0277]: the trait bound `redis::aio::Connection<Pin<Box<dyn AsyncStream + Send + Sync>>>: DerefMut` is not satisfied
    --> src\main.rs:8:22
     |
8    |   redis::transaction(&mut conn, &[], |con, pipe| {
     |   ------------------ ^^^^^^^^^ the trait `DerefMut` is not implemented for `redis::aio::Connection<Pin<Box<dyn AsyncStream + Send + Sync>>>`
     |   |
     |   required by a bound introduced by this call
     |
     = help: the following other types implement trait `redis::ConnectionLike`:
               redis::Connection
               redis::Client
     = note: required for `redis::aio::Connection<Pin<Box<dyn AsyncStream + Send + Sync>>>` to implement `redis::ConnectionLike`
note: required by a bound in `transaction`
    --> C:\Users\GAME\.cargo\registry\src\index.crates.io-6f17d22bba15001f\redis-0.24.0\src\connection.rs:1494:8
     |
1493 | pub fn transaction<
     |        ----------- required by a bound in this function
1494 |     C: ConnectionLike,
     |        ^^^^^^^^^^^^^^ required by this bound in `transaction`

I am following the synchronous form of transaction (from sync example), I think it will also work for asynchronous connection, but it doesn't seems right. No examples nor documentation were useful...

(Still not my area but from what I read) you can't use redis::transaction with redis::aio::Connection. redis::transaction requires redis::ConnectionLike, but redis::aio::Connection implements redis::aio::ConnectionLike, a different trait.

(It's a red/green colouring issue.)

So it seems ideally you'd have a redis::aio::transaction, but this issue was closed and so was this one, with comments like

Transactions can be used using pipeline objects.

aio::ConnectionLike is implemented for connection_manager, and pipeline objects can be used on it for transactions.

which would be great[1] if you have the domain knowledge or if the documentation pointed you in the right direction. But I don't and it doesn't.

Maybe the code in this PR, or in the linked example, can meet your needs.


  1. perhaps ↩ī¸Ž

3 Likes

hi @quinedot thank you so much for pointing me to these links. I really appreaciate any help in this very specific problem.