即使Redis是单线程的,但是在多线程的情况下,可能会出现脏读这样的问题。比如,线程A从Redis读到key X的值=1,线程B也读到1,但是线程A读到之后进行计算将其改为2,线程B的值还是1,还在用拿到的1进行业务计算,这样就会出问题。可以通过下面代码,通过setnx设置一把锁,每个线程过来,只有获取了锁才能继续操作,否则就重试,获得锁的线程执行自己的计算操作,执行完之后,删掉锁,这样其他的线程再进来执行的时候,数据就是最新的。不会出现脏读的问题。
private void LockRedisUpdate(){
Jedis jedis = new Jedis();
// 此处检测并加锁
long check = jedis.setnx("lock", "lock it");
if(check==0){
// 如果已经有锁了,则重试
LockRedisUpdate();
return;
}
// 操作
long res = jedis.incr("counter");
if(res!=0){
// 执行完成之后删掉锁
jedis.del("lock");
}
}