首先redis是单进程的形式运行,所以每个redis的命令都具备原子性
那么redis的并发问题是如何产生的呢?
举例:
有个键,假设名称为myNum,里面保存的是阿拉伯数字,假设现在值为1,存在多个连接对myNum进行操作的情况,这个时候就会有并发的问题。假设有两个连接linkA和linkB,这两个连接都执行下面的操作,取出myNum的值,+1,然后再存回去,看看下面的交互:
linkA get myNum => 1
linkB get myNum => 1
linkA set muNum => 2
linkB set myNum => 2
即,我们以为理想的的线程发生顺序是(redis接收到的4条命令顺序):
linkA get
linkA set
linkB get
linkB set
然而,由于并发性,有可能的顺序为:
linkA get myNum => 1
linkB get myNum => 1
linkA set muNum => 2
linkB set myNum => 2
so,并发就这样产生了
这里要提到几个概念
1. redis中的事务
- redis事务使用multi、exec命令(事务中的命令是在exec之后才执行的)
- redis事务的命令中有一条执行失败,不会回滚
so.以上的问题导致redis的事务不具备原子性,所以这里要使用到第二个概念
2. watch
WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到EXEC命令
举例:
利用watch实现incr
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC