ApsaraDB for Redis supports the transaction mechanism defined in Redis.
Scenario
You can run MULTI, EXEC, DISCARD, WATCH, and UNWATCH commands to perform atomic operations in transactions.
Sample code 1: Two clients process 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);
//The password of the ApsaraDB for Redis instance.
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 the other client.
new KVStoreTranscationTest().new OtherKVStoreClient().start();
Thread.sleep(500);
Transaction tx = jedis.multi();//Starts the transaction.
//The following operations are 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 subsequent operations in a transaction. Other thread operations cannot be performed.
tx.incr(client1_key);
Thread.sleep(300);//The suspension of the thread does not affect the subsequent operations in a transaction. Other thread operations cannot be performed.
tx.incr(client1_key);
Thread.sleep(200);//The suspension of the thread does not affect the subsequent operations in a transaction. Other thread operations cannot be performed.
tx.incr(client1_key);
List<Object> result = tx.exec();//Performs the operations.
//Parses and prints the results.
for(Object rt : result){
System.out.println("Client 1 > transaction in progress> "+rt.toString());
}
jedis.close();
}
class OtherKVStoreClient extends Thread{
@Override
public void run() {
Jedis jedis = new Jedis(host, port);
//The password of the ApsaraDB for Redis instance.
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 transaction operations submitted by client 1 are sequentially implemented. Client 2 sends requests to perform an operation on another key during this period, but the operation is blocked. Client 2 must wait until all the transaction operations of client 1 are complete.
Client 2 > 101
Client 2 > 102
Client 2 > 103
Client 2 > 104
Client 1> transaction in progress> 1
Client 1> transaction in progress> 2
Client 1> transaction in progress> 3
Client 1> transaction in progress> 4
Client 1> transaction in progress> 5
Client 2 > 105
Client 2 > 106
Client 2 > 107
Client 2 > 108
Client 2 > 109
Client 2 > 110
Sample code 2: Two clients process the same key
By modifying the preceding code, the two clients can process 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 following output is displayed: The two clients are in different threads but process the same key. However, while client 1 uses the transaction mechanism to process this key, client 2 is blocked and must wait until all the transaction operations of client 1 are completed.
Client 2 > 101
Client 2 > 102
Client 2 > 103
Client 2 > 104
Client 1> transaction in progress> 105
Client 1> transaction in progress> 106
Client 1> transaction in progress> 107
Client 1> transaction in progress> 108
Client 1> transaction in progress> 109
Client 2 > 110
Client 2 > 111
Client 2 > 112
Client 2 > 113
Client 2 > 114
Client 2 > 115