redis USES watch to realize its idea

  • 2020-06-07 05:33:16
  • OfStack

This article shares the specific code of redis using watch for your reference. The specific content is as follows

1. Use watch and optimistic lock
2, do not use pessimistic locks, because the waiting time is very long, slow response
3. Do not use queues, because the amount of concurrency causes the queue memory to increase instantaneously

Code:


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import redis.clients.jedis.Jedis;

/**
 * redis The test for 
 * 
 * @author 10255_000
 * 
 */
public class RedisTest {
 public static void main(String[] args) {
  final String watchkeys = "watchkeys";
  ExecutorService executor = Executors.newFixedThreadPool(20);

  final Jedis jedis = new Jedis("192.168.3.202", 6379);
  jedis.set(watchkeys, "0");//  reset watchkeys for 0
  jedis.del("setsucc", "setfail");//  Clear out the successful and the unsuccessful 
  jedis.close();

  for (int i = 0; i < 10000; i++) {//  test 1 Simultaneous visit of 10,000 people 
   executor.execute(new MyRunnable());
  }
  executor.shutdown();
 }
}


import java.util.List;
import java.util.UUID;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class MyRunnable implements Runnable {

 String watchkeys = "watchkeys";//  monitoring keys
 Jedis jedis = new Jedis("192.168.3.202", 6379);

 public MyRunnable() {
 }

 @Override
 public void run() {
  try {
   jedis.watch(watchkeys);// watchkeys

   String val = jedis.get(watchkeys);
   int valint = Integer.valueOf(val);
   String userifo = UUID.randomUUID().toString();
   if (valint < 10) {
    Transaction tx = jedis.multi();//  Open the transaction 

    tx.incr("watchkeys");

    List<Object> list = tx.exec();//  Commit the transaction, if at this point watchkeys Has been changed, returns null
    if (list != null) {
     System.out.println(" User: " + userifo + " Buying success, the current number of successful buying :"
       + (valint + 1));
     /*  Snap up successful business logic  */
     jedis.sadd("setsucc", userifo);
    } else {
     System.out.println(" User: " + userifo + " For failure ");
     /*  Snap up failed business logic  */
     jedis.sadd("setfail", userifo);
    }

   } else {
    System.out.println(" User: " + userifo + " For failure ");
    jedis.sadd("setfail", userifo);
    // Thread.sleep(500);
    return;
   }

  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   jedis.close();
  }

 }

}

Redis's support for things is relatively simple at the moment. Redis can only guarantee that commands in a transaction initiated by client can be executed consecutively, but subsequent commands will not be rolled back before they fail. No other client commands are inserted. When an client issues the multi command in a row, the link will enter a transaction context. The subsequent commands of the link will not be executed immediately, but put into the queue first. When the exec command is executed, redis will execute all commands in the queue sequentially. If there is a command error in the queue, it will not be rolled back.

Optimistic locking: Most implementations are based on the data version (version) recording mechanism. In the version solution based on database table, 1 generally means to read and retrieve data by adding 1 "version" field to the database table, read the version number 1 together, and then update the version number +1. At this point, the version number of the submitted data is compared with the corresponding record version number of the database table. If the submitted data version number is greater than the current version number of the data, it will be updated; otherwise, it will be regarded as the past data.

In Redis, use the watch command to implement optimistic locking (watch key):
The watch command monitors a given key, and when exec is used, if the monitored key has changed since the call to watch, the transaction will fail, or you can call wathc how long to monitor multiple key. This allows you to add optimistic locks to the key specified. Note that watch's can be valid for the entire connection. The transaction is the same. If the connection is broken, monitoring and transactions are automatically cleared. Of course the exec, discard, unwatch commands clear all monitoring in the connection.


Related articles: