Process transactions

更新时间:
复制 MD 格式

Tair (Redis OSS-compatible) supports Redis transactions. Use the MULTI, EXEC, DISCARD, WATCH, and UNWATCH commands to run atomic operations.

Redis transactions differ from relational database transactions. If an operation fails or you run DISCARD, Redis does not roll back the transaction.

Code examples

Example 1: Two clients operate on different keys

Sample code:

package transcation.kvstore.aliyun.com;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class KVStoreTranscationTest {
    static final String host = "xxxxxx.m.cnhza.kvstore.aliyuncs.com";
    static final int port = 6379;
    static final String password = "password";
    //  Note: The two keys have different content.
    static String client1_key = "KVStore-Transcation-1";
    static String client2_key = "KVStore-Transcation-2";
    public static void main(String[] args) {
        Jedis jedis = new Jedis(host, port);
        String authString = jedis.auth(password);  // Instance password (password)
        if (!authString.equals("OK")) {
            System.err.println("Authentication failed: " + authString);
            jedis.close();
            return;
        }
        jedis.set(client1_key, "0");
        // Start another thread to simulate another client.
        new KVStoreTranscationTest().new OtherKVStoreClient().start();
        Thread.sleep(500);
        Transaction tx = jedis.multi();// Start the transaction.
        // The following operations are submitted to the server as an atomic operation.
        tx.incr(client1_key);
        tx.incr(client1_key);
        Thread.sleep(400);// Pausing this thread does not affect consecutive operations in the transaction. Other threads cannot execute operations either.
        tx.incr(client1_key);
        Thread.sleep(300);// Pausing this thread does not affect consecutive operations in the transaction. Other threads cannot execute operations either.
        tx.incr(client1_key);
        Thread.sleep(200);// Pausing this thread does not affect consecutive operations in the transaction. Other threads cannot execute operations either.
        tx.incr(client1_key);
        List<Object> result = tx.exec();// Execute the transaction.
        // Parse and print the results.
        for(Object rt : result){
            System.out.println("Client 1 > In transaction > "+rt.toString());
        }
        jedis.close();
    }
    class OtherKVStoreClient extends Thread{
        @Override
        public void run() {
            Jedis jedis = new Jedis(host, port);
            String authString = jedis.auth(password);// Instance password (password)
            if (!authString.equals("OK")) {
                System.err.println("AUTH Failed: " + authString);
                jedis.close();
                return;
            }
            jedis.set(client2_key, "100");
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Client 2 > "+jedis.incr(client2_key));
            }
            jedis.close();
        }
    }
}

Run the program with the correct endpoint and password for your Tair (Redis OSS-compatible) instance. In the output, client1's transaction operations execute as an atomic block. Client2 is blocked until the transaction completes, even though it uses a different key.

Expected output:

Client 2 > 101
Client 2 > 102
Client 2 > 103
Client 2 > 104
Client 1 > In transaction > 1
Client 1 > In transaction > 2
Client 1 > In transaction > 3
Client 1 > In transaction > 4
Client 1 > In transaction > 5
Client 2 > 105
Client 2 > 106
Client 2 > 107
Client 2 > 108
Client 2 > 109
Client 2 > 110

Example 2: Two clients operate on the same key

This example modifies Example 1 so both clients operate on the same key. The rest of the code is unchanged.

    ... ... 
//  Note: The two keys now have the same content.
    static String client1_key = "KVStore-Transcation-1";
    static String client2_key = "KVStore-Transcation-1";
    ... ...

Run the modified program. When client1 uses a transaction on the shared key, client2 is blocked until the transaction completes.

Client 2 > 101
Client 2 > 102
Client 2 > 103
Client 2 > 104
Client 1 > In transaction > 105
Client 1 > In transaction > 106
Client 1 > In transaction > 107
Client 1 > In transaction > 108
Client 1 > In transaction > 109
Client 2 > 110
Client 2 > 111
Client 2 > 112
Client 2 > 113
Client 2 > 114
Client 2 > 115