Scenario introduction

ApsaraDB for Redis supports a mechanism to define transactions, as in Redis. This allows you to use the MULTI, EXEC, DISCARD, WATCH, and UNWATCH commands to execute atomic transactions.

Note that the definition of transaction in Redis is different from that in relational databases. If an operation fails or the transaction is canceled by the DISCARD command, Redis does not perform the "transaction rollback".

Sample code 1: Two clients operate on different keys

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 that these 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);
        //ApsaraDB for Redis instance password
        String authString = jedis.auth(password);//password
        if (! authString.equals("OK")) {
            System.err.println("authentication failed: " + authString);
            jedis.close();
            return;
        }
        jedis.set(client1_key, "0");
        //Starts another thread to simulate another client
        new KVStoreTranscationTest().new OtherKVStoreClient().start();
        Thread.sleep(500);
        Transaction tx = jedis.multi();//Starts the transaction
        //The following operations are collectively submitted to the server as "atomic operations"
        tx.incr(client1_key);
        tx.incr(client1_key);
        Thread.sleep(400);//The suspension of the thread does not affect the consecutively executed operations in a transaction. Other thread operations cannot be executed.
        tx.incr(client1_key);
        Thread.sleep(300);//The suspension of the thread does not affect the consecutively executed operations in a transaction. Other thread operations cannot be executed.
        tx.incr(client1_key);
        Thread.sleep(200);//The suspension of the thread does not affect the consecutively executed operations in a transaction. Other thread operations cannot be executed.
        tx.incr(client1_key);
        List<Object> result = tx.exec();//Submits the operation for execution
        //Parses and prints out 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);
            //ApsaraDB for Redis instance password
            String authString = jedis.auth(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();
        }
    }
}

Output 1

After you access the ApsaraDB for Redis instance with the correct address and password and run the preceding Java code, the following output is displayed. Here, we can see that Client 1 and Client 2 are in different threads. The operations in the transaction submitted by Client 1 are executed sequentially. Client 2 requests for operating on another key during this period, but the operation is blocked and Client 2 has to wait until all the operations in the Client 1 transaction have been completed.

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

Sample code 2: Two clients operate on the same key

By slightly modifying the preceding code, we can have the two clients operate on the same key. The other parts of the code remain unchanged.

    ...... 
// *** Note that the content of these two keys is now the same
    static String client1_key = "KVStore-Transcation-1";
    static String client2_key = "KVStore-Transcation-1";
    ......

Output 2

After the modified Java code is executed, the output is displayed as follows. We can see that the two clients are in different threads but operate on the same key. However, while Client 1 uses the transaction mechanism to operate on this key, Client 2 is blocked and has to wait until all the operations in the Client 1 transaction are completed.

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