文章目录
redis中的事务
Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
特性
- 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
- 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
开启事务(multi)
multi命令用于开启一个事务,它总是返回 OK 。
提交事务(exec)
使用multi开启事务后,客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个缓存队列中, 当 exec命令被调用时, 所有队列中的命令才会被执行。
放弃事务(discard)
discard命令用在multi命令之后,exec命令之前, 通过调用 discard , 客户端可以清空事务队列, 并放弃执行事务,也就以为整个事务内的所有缓存命令都不会被执行
需要注意的是:执行了discard命令后,同一个事务里exec命令就不能再执行,执行会抛出错误
事务监控(watch)
使用watch监视一个或者多个key,跟踪key的value修改情况,如果有key的value值在事务exec执行之前被修改了,整个事务被取消。exec返回提示信息,表示事务已经失败。
注意:在事务内修改了监控的key的值,整个事务同样会被取消
案例一
案例二
取消事务监控(unwatch)
- 可以通过
unwatch
命令取消当前实例对所有key
的监视 - 一但执行
exec
开启事务的执行后,无论事务是否执行成功,watch
对变量的监控都将被取消,所以当事务执行失败后,需重新执行watch
命令对变量进行监控
redis队列事务的隐患
redis的事务是将命令存储到缓存一起执行,如果遇到语法的错误,事务会自动放弃,但是若是逻辑上有错误,语法没错误,redis的事务会一直执行下去,某个逻辑导致的错误出现后,事务并不会停止,会继续执行下面的命令
锁
公共锁(setnx)
我们在使用一个变量时,需要保证我自己在使用时,别人不能使用,最好的方法就是为了这个变量加把锁 ,
setnx
命令就可以做到
语法
redis-cli> setnx lock_keyname value
- 命令在指定的 key 不存在时,为 key 设置指定的值,
- 设置成功,返回 1 。 设置失败,返回 0 。返回0就代表这个锁被别人锁着,我们不能用
- 需要注意:必须约定所有的客户端都用同一把锁,这样才有效,因为这是一种设计概念,要依赖规范性
案例
释放锁
因为锁也是key,所以只需要删除对应的key,锁也就释放了
del keyname
公共锁改良
通常我们在实际生活中会出现这种状况,如果我们对当前使用的变量进行了lock(锁),这个时候电脑宕机,那么这个锁就会一直存在,这种情况我们最好是对锁加个有效时间,这样不管我们的电脑宕不宕机,过了有效时间,锁就会释放
# 指定key在多少秒内有效
expire lock-key second
# 指定key在多少毫秒内有效
pexpire lock-key millisecond