Transaction

Last Updated: Jul 14, 2017

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.

Please be noted that the definition of transaction in Redis is slightly different from that in relational databases. If an operation fails or the transaction is cancelled by the DISCARD command, Redis does not perform transaction rollback.

Sample code 1: Two clients operate on different keys

  1. package transcation.kvstore.aliyun.com;
  2. import java.util.List;
  3. import redis.clients.jedis.Jedis;
  4. import redis.clients.jedis.Transaction;
  5. public class KVStoreTranscationTest {
  6. static final String host = "xxxxxx.m.cnhza.kvstore.aliyuncs.com";
  7. static final int port = 6379;
  8. static final String password = "password";
  9. //**Note that the two keys have different values
  10. static String client1_key = "KVStore-Transcation-1";
  11. static String client2_key = "KVStore-Transcation-2";
  12. public static void main(String[] args) {
  13. Jedis jedis = new Jedis(host, port);
  14. //ApsaraDB for Redis instance password
  15. String authString = jedis.auth(password);//password
  16. if (!authString.equals("OK")) {
  17. System.err.println("认证失败: " + authString);
  18. jedis.close();
  19. return;
  20. }
  21. jedis.set(client1_key, "0");
  22. //Starts another thread to simulate another client
  23. new KVStoreTranscationTest().new OtherKVStoreClient().start();
  24. Thread.sleep(500);
  25. Transaction tx = jedis.multi();//Starts the transaction
  26. //The following operations are collectively submitted to the server for processing as "atomic operations"
  27. tx.incr(client1_key);
  28. tx.incr(client1_key);
  29. Thread.sleep(400);//Here, the thread's suspension has no effect on the successive operations in the transaction, but it also suspends the operations of other threads
  30. tx.incr(client1_key);
  31. Thread.sleep(300);//Here, the thread's suspension has no effect on the successive operations in the transaction, but it also suspends the operations of other threads
  32. tx.incr(client1_key);
  33. Thread.sleep(200);//Here, the thread's suspension has no effect on the successive operations in the transaction, but it also suspends the operations of other threads
  34. tx.incr(client1_key);
  35. List<Object> result = tx.exec();//Submitted for execution
  36. //Parses and prints out the results
  37. for(Object rt : result){
  38. System.out.println("Client 1 > 事务中> "+rt.toString());
  39. }
  40. jedis.close();
  41. }
  42. class OtherKVStoreClient extends Thread{
  43. @Override
  44. public void run() {
  45. Jedis jedis = new Jedis(host, port);
  46. //ApsaraDB for Redis instance password
  47. String authString = jedis.auth(password);// password
  48. if (!authString.equals("OK")) {
  49. System.err.println("AUTH Failed: " + authString);
  50. jedis.close();
  51. return;
  52. }
  53. jedis.set(client2_key, "100");
  54. for (int i = 0; i < 10; i++) {
  55. try {
  56. Thread.sleep(300);
  57. } catch (InterruptedException e) {
  58. e.printStackTrace();
  59. }
  60. System.out.println("Client 2 > "+jedis.incr(client2_key));
  61. }
  62. jedis.close();
  63. }
  64. }
  65. }

Output 1

After you access the ApsaraDB for Redis instance with the correct address and password and run the above 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 Client 1’s transaction have been completed.

  1. Client 2 > 101
  2. Client 2 > 102
  3. Client 2 > 103
  4. Client 2 > 104
  5. Client 1 > Transaction > 1
  6. Client 1 > Transaction > 2
  7. Client 1 > Transaction > 3
  8. Client 1 > Transaction > 4
  9. Client 1 > Transaction > 5
  10. Client 2 > 105
  11. Client 2 > 106
  12. Client 2 > 107
  13. Client 2 > 108
  14. Client 2 > 109
  15. Client 2 > 110

Sample code 2: Two clients operate on the same key

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

  1. ... ...
  2. //**Note that the values of the keys are the same
  3. static String client1_key = "KVStore-Transcation-1";
  4. static String client2_key = "KVStore-Transcation-1";
  5. ... ...

Output 2

After running the modified Java code, 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 Client 1’s transaction are completed.

  1. Client 2 > 101
  2. Client 2 > 102
  3. Client 2 > 103
  4. Client 2 > 104
  5. Client 1 > Transaction > 105
  6. Client 1 > Transaction > 106
  7. Client 1 > Transaction > 107
  8. Client 1 > Transaction > 108
  9. Client 1 > Transaction > 109
  10. Client 2 > 110
  11. Client 2 > 111
  12. Client 2 > 112
  13. Client 2 > 113
  14. Client 2 > 114
  15. Client 2 > 115
Thank you! We've received your feedback.