#Proper use of Connection for Transactions/Multi

5 messages · Page 1 of 1 (latest)

eager hinge
#

Hello, I was looking at lettuce wiki and I have some doubts.

We use ConnectionPooling by following rules described into the wiki in section Advanced Usage -> Connection Pooling

I have read that since multi is blocking the connection, that in this specific case, multi should not be used by shared connections (eg pooling situation?).

In this situation, where we normally execute commands and also in some methods .multi() , which approach should be taken?

We rely for now on synchronous API calls done in CompletableFutures<?> runned in virtual threads.

eager hinge
#

Proper use of Connection for Transactions/Multi

round kelp
#

Hello @eager hinge
Lettuce is designed as a multiplexing driver, meaning - multiple application threads can execute commands simultaneously through a single Lettuce connection. However there are a few scenarios when this is not true.

  1. Blocking Commands (BLPOP, BRPOP, BLMOVE, etc.) - all commands after the blocking one are stuck waiting

Thread 1: BLPOP mylist 30 ──────────────────────────────→ (waiting for data...) Thread 2: GET key ──→ ??? STUCK waiting Thread 3: SET foo ──→ ??? STUCK waiting ↑ Commands are QUEUED behind the blocking command

  1. Transactions (MULTI/EXEC) - as the first example causes some performance degradation, transactions are worse, because they can break the connection state.

Thread 1: MULTI ← Connection enters "transaction mode" Thread 1: SET key1 val1 → QUEUED Thread 2: GET foo → QUEUED (oops! now part of Thread 1's transaction!) Thread 1: SET key2 val2 → QUEUED Thread 1: EXEC ← Executes ALL queued commands including Thread 2's!

Solution - in those cases you should use dedicated connection.Example:
CompletableFuture.supplyAsync(() -> { try (var conn = pool.borrowObject()) { // Dedicated connection var sync = conn.sync(); sync.multi(); sync.set("key1", "v1"); sync.set("key2", "v2"); return sync.exec(); } }, virtualThreadExecutor);

eager hinge
round kelp
#

As long as you are doing -> get connection -> multi -> commands... -> exec -> return conncetion to pool you should be fine. Its no problem that the pool is shared.