Questions about the atomicity Test of redis

I know that a single operation of redis is atomic, and multiple operations on redis in the code will not guarantee the atomicity of the entire operation flow.

for example, in the following code, assuming that the value of nums key is 50 and 1000 visits are made to it using the ab.exe tool, the concurrency number is 100. In theory, the result should be negative.

but I have tested nums with a value of 1 many times. Is it because I am testing in the wrong way or is there something wrong with it?

$nums = $redis->get("nums");
if($nums > 1)
    $redis->decr("nums");
Apr.01,2021

you wrote judgment, decreasing 1 when it's greater than 1
you don't execute it when you reduce it to 1, how can it be used as a basis for testing atomicity?


concurrency like yours is hard to test, and it is possible to do so with a negative number. But consider that your computer has 4 cores and 8 threads, and at most 8 requests are executed at the same time, which is a very small amount of concurrency for redis. So I think there is no problem because the amount of concurrency is small, in fact, there will be problems.


I don't know how ab.exe tests work. You can write a multithreaded call and know that it will generate negative values.

//phpjavatest
import redis.clients.jedis.Jedis;


public class Test {
    
    public static void main(String[] args) throws Exception {
        
        Jedis jedis = getJedis();
        jedis.set("nums", 50+"");
        close(jedis);
        
        for(int i = 0;i < 1000;iPP){ //1000
            new Thread(new MyTask()).start();
        }
        
    }
    
    public static  Jedis getJedis(){
        Jedis j = new Jedis("xxxxx", 6379);
        j.auth("xxxx");
        return j;
    }
    
    public static void close(Jedis jedis){
        if(null == jedis){
            return;
        }
        jedis.close();
    }
}

class MyTask implements Runnable{
    @Override
    public void run() {
        Jedis j = Test.getJedis();
         String numStr = j.get("nums");
         Integer nums = Integer.valueOf(numStr);
        
        if(nums > 1){
             j.decr("nums");
        }else{
             System.out.println(nums);
        }
        Test.close(j);
    }
}

the output is negative.

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1eac74c-47ea0.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1eac74c-47ea0.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?