Redis achieve business affairs and spike

Redis Affairs

Redis transaction can perform a plurality of commands (executed sequentially serialized, can not be inserted in the other command, allowed stopper) allows performing a command in a separate step, and with the following two important guarantee :
1, Redis will all command a transaction serialization, and then executed in order.
2 and will not be inserted into other commands execution, not allowed to appear Gasser behavior

It is placed in a batch operation before sending queue buffer EXEC command.
After receiving EXEC command to enter the transaction execution, transaction arbitrary command execution fails, the rest of the command is still being executed.
During the execution of a transaction, other command request submitted by the client will not be inserted into the transaction execution command sequence.

From start to execute a transaction will go through three stages

(1)开始事务
(2)命令入队
(3)执行事务

Redis transaction involved five commands:

  • Multi : start a transaction , the transaction start command is MULTI, the command returns OK message Redis does not support nested transactions, MULTI perform multiple commands and execute the same effect once nested MULTI execute commands, Redis just returns an error. message.
  • Exec : performing a transaction , EXEC submitted command transaction, command sequences transaction to be performed (or not performed, such as optimistic locking failure, etc.) the command returns the response array, the contents of the corresponding commands in the transaction execution result.
  • Watch : WATCH command optimistic locking is started, the command is the key parameter (can have multiple), Redis will execute client object WATCH commands and key associates, if other clients to modify these key, then execute the command WATCH the client will be setting a flag optimistic lock failure. the command must be executed before the start of the transaction, that the implementation MULTI WATCH command before executing the command, otherwise invalid, and returns an error message.
  • unwatch : unwatch command to cancel the current optimistic locking key client object, the client object of the transaction will be submitted become unconditional implementation.
  • discard : DISCARD command will end the transaction, and will discard all of the command sequence.

Spike functional design

So how to achieve a transaction with Redis spike function? The answer is to use a watch, watch to monitor changes in certain key, and when the transaction is executed, if the other client can change this value corresponding to, will lead to the current client transaction is not executed, that is similar to the optimistic locking mechanism.

Sample code is as follows:
First, do not watch code:
examples to have 10 coupons, there are more than rob the need to provide spike function.
First, a key is provided for in the num value of 0 redis:
command: SET num 0

MyThread categories:

import com.itheima.RedisPoolUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;
import java.util.UUID;

public class MyThread extends Thread{

        @Override
        public void run() {

            for (int i = 0; i < 10; i++){
                Jedis jedis = RedisPoolUtil.getJedis();
                String num = jedis.get("num");
                int n = Integer.parseInt(num);

                if (n < 10){
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    jedis.incr("num");
                    String name = UUID.randomUUID().toString().replaceAll("-", "");
                    System.out.println(name + "抢到一张优惠券");
                }
            }
        }
}

The main function:

public class TestMain {

    public static void main(String[] args) {
    
        for (int i = 0; i < 5; i++){
            MyThread thread = new MyThread();
            thread.start();
        }
        
    }
}

RedisPoolUtil categories:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class RedisPoolUtil {
    private static JedisPool pool;
    static {
        //1、连接池redis pool 基本配置信息
        JedisPoolConfig poolConfig=new JedisPoolConfig();
        poolConfig.setMaxTotal(5);
        poolConfig.setMaxIdle(1);
        //其他配置

        //2、连接池
        String host="192.168.18.132";
        int port=6379;
        pool=new JedisPool(poolConfig,host,port);

    }

    public static Jedis getJedis(){
        Jedis jedis=pool.getResource();
        jedis.auth("root");
        return jedis;
    }

    //关闭连接
    public static void close(Jedis jedis){
        jedis.close();
    }
}

When the code is executed, it will be found in more than 10 individual grab coupons.
Code optimization, using the transaction:
the addition Watch, the following code, modified Mythred categories:

import com.itheima.RedisPoolUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;
import java.util.UUID;

public class MyThread extends Thread{
    @Override
    public void run() {

        for (int i = 0; i < 10; i++){
//          Jedis jedis = RedisConnection.getJedis();
            Jedis jedis = RedisPoolUtil.getJedis();
            String watch = jedis.watch("num");
            String num = jedis.get("num");
            int n = Integer.parseInt(num);
            if (n < 10){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                Transaction transaction = jedis.multi();
                transaction.incr("num");
                List<Object> list = transaction.exec();
                String name = UUID.randomUUID().toString().replaceAll("-", "");

                if (list == null || list.size() == 0){
                    System.out.println(watch + "==="+list+"----" + name + "手慢了,抢票失败");
                }else {
                    System.out.println(watch + "==="+list+"----" + name + "抢到一张优惠券");
                }
            }
        }
    }
}

The test results, you will find that although there will be as many people try to steal, but still only 10 people can grab.

Published 178 original articles · won praise 185 · views 80000 +

Guess you like

Origin blog.csdn.net/Sophia_0331/article/details/104792656