dragonflydb / dragonfly

A modern replacement for Redis and Memcached
https://www.dragonflydb.io/
Other
25.92k stars 950 forks source link

MULTI does not allow SELECT #4120

Open LucHeart opened 4 days ago

LucHeart commented 4 days ago

Describe the bug Im trying to use Dragonfly DB with StackExchange.Redis, which is the most popular redis library for C#. However transactions do not work at all. After some debugging, I figured out the core issue. The issue is that dragonflydb doesnt seem to allow SELECT during MULTI. Dont ask me why it does that, but it does.

The command that SE.Redis sends is for example

SELECT 0 MULTI JSON.SET LoginSession:test . {"Id":"test"} SELECT 0 EXEC

To Reproduce in CLI Steps to reproduce the behavior:

  1. Start a new transaction with MULTI
  2. SELECT 0 (You can already see the error message)
  3. EXEC to see the final error message that the library also responds with

Expected behavior SELECT should be allowed in transactions, especially SELECT 0

Screenshots DragonFly logs {8486689F-470C-447B-9512-1814CC9F7702}

Wireshark capture {7D5E22B6-68B2-4246-A05E-2D49432D8AD1}

Environment (please complete the following information):

Reproducible Code Snippet

        var transaction = _connectionMultiplexer.GetDatabase().CreateTransaction();

        var executeAsync = transaction.ExecuteAsync("JSON.SET", new object[]
        {

                "LoginSession:test",
            ".",
            "{\"Id\":\"test\"}"
        });
        await transaction.ExecuteAsync();
        await executeAsync;

Additional context This also affects libraries that build upon StackExchange.Redis like Redis.OM, this is where I encountered the bug the first time.

romange commented 4 days ago

Thanks. Do you know if database id in select can actually change during MULTI? we can definitely relax this restriction if database id has already been 0, or the same ID before any select in MULTI

romange commented 4 days ago

especially SELECT 0 - indeed, it's a low effort to allow

LucHeart commented 4 days ago

No I dont think it can change. _connectionMultiplexer.GetDatabase() gets the database you desire. Defaults to 0 here, after that point it cannot switch database anymore.

Well technically you can send a raw query but i dont think we need to worry about that. Not even sure if multi does support multiple databases in a single transaction