Help Center/ GeminiDB/ GeminiDB Redis API/ Development Reference/ Processing Transactions on a GeminiDB Redis Instance
Updated on 2024-10-30 GMT+08:00

Processing Transactions on a GeminiDB Redis Instance

About Transactions

A transaction is a logical unit which groups a set of read or write operations, so that they either succeed or fail collectively. In a connection, after a client executes the multi command, a GeminiDB Redis instance starts to cache subsequent commands in a queue. When the client sends the exec command, the GeminiDB Redis instance executes all commands in the queue in sequence. If a command fails, transactions will be rolled back. All commands are either successful or failed.

Table 1 Related commands

Command

Description

WATCH

Monitors one or more keys. If a key is modified before a transaction is executed, the whole transaction aborts.

UNWATCH

Flushes all watched keys.

MULTI

Identifies start of a transaction block.

EXEC

Executes all commands in a transaction block.

DISCARD

Flushes queued commands in a transaction bock and exits the transaction block.

Precautions:

  • When a proxy cluster is used, all keys in a transaction must have the same hashtag to ensure transaction atomicity. If hashtag is not used, a transaction will be split into common commands. In this case, the atomicity cannot be ensured.
  • Atomic transactions mean that all of them will either succeed or fail, so you need to pay attention to command validity when compiling a transaction.
  • The commands in a transaction are executed in sequence, so you need to pay attention to the command sequence when compiling a transaction.
  • Do not pack too many or complex commands in a single transaction, or requests may be blocked or the instance status may be abnormal.

Example Code

When the client modifies key1 and key2 at the same time in a transaction, they are either successfully modified or fail to be modified at the same time.

package nosql.cloud.huawei.jedis;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class TranscationTest {
    private static final String host = "127.0.0.1";
    private static final int port = 6379;
    private static final String pwd = "password";

    private static Jedis jedis;
    static {
        jedis = new Jedis(host, port);
        String authString = jedis.auth(password);
        if (!authString.equals("OK")) {
            jedis.close();
            jedis = null;
        }
    }
    public static void main(String[] args) {
        if (jedis == null) {
            return;
        }

        String str_key1 = "{str}key1";
        String str_key2 = "{str}key2";
        jedis.set(str_key1, "0");
        jedis.set(str_key2, "0");
        jedis.watch(str_key1);
        // Starts processing transactions.
        Transaction tx = jedis.multi();
        tx.set(str_key1, "500");
        tx.get(str_key1);
	tx.set(str_key2, "1000");
        tx.get(str_key2);
        List<Object> result = tx.exec();
        if (result.isEmpty()) {
           System.out.println ("Error: The transaction is interrupted.");
        } else {
          System.out.println ("Succ: The transaction is executed successfully.");
        }
        System.out.println("str_key1: {}, str_key2: {}", jedis.get(str_key1), jedis.get(str_key2));
        jedis.close();
    }
}