redis事务和锁机制
Posted 两片空白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis事务和锁机制相关的知识,希望对你有一定的参考价值。
目录
事务定义
redis事务是一个单独的隔离操作:事务中的所有命令都会序列化,按顺序的执行。事务中在执行过程中,不会被其他客户端发送过来的请求命令打断。
redis事务的主要作用就是串联多个命令,防止别的命令插队。
redis事务实现操作顺序的执行,是通过队列的实现的。
事务操作命令
事务操作的基本命令是:Multi,Exec,discard。
从输入Multi命令开始,输入的命令都会依次进入到命令队列中,但是不会执行,直到输入Exec后,Redis将命令队列中的命令依次执行。
组队过程中可以通过discard来放弃组队。
案例:
redis事务的错误处理
- 在组队过程中,某个命令出现了报错,在执行时,队列的所有命令都不会执行。
- 在组队过程中,都是正确的,但是,在执行时某个命令出现了错误,那只有错误命令不会被执行,其他正确的命令都会执行。
redis事务冲突问题
什么是冲突?以及为什么要解决冲突?
模拟抢票的场景。当只有一张票时,此时,三个人看到同一张票,同时抢。在代码中表现为,三个线程同时从redis中获取票数,此时会有冲突,如果不解决冲突,三个线程取到票的数量都为1,都可以买到票,但是实际只有一张票。此时就会有问题。
redis解决事务冲突的方法
- 悲观锁
顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。这样别人拿数据的时候就会阻塞直到拿到锁。传统的关系型数据库中就用到了很多这样的锁机制。比如:行锁,表锁等,读锁,写锁等,都是在操作前上锁。
这种锁的缺点会导致效率变低。
比如上面买票的例子,三个人买一张票。第一个人买时,就会上锁,第二个和第三个人买不了,直到第一个人买完。
- 乐观锁
顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁。但是在每次拿数据时会判断一下有没有人去更新这个数据,可以使用版本号等机制。
乐观锁适用于多读的应用类型,这样可以提高吞吐量。redis就是利用这种check-and-set机制实现事务的。
比如上面买票的例子,三个人同时抢到这一张票,此时版本号为v1,但是第一个人实际抢到了这张票,在设置票数时,将数据库中票数量的版本号设为v1.1,第二个人修改票数量时,比较版本号,此时版本号不相同,不会进行操作,需要获得新数据才可以进行操作。
- 监视WATCH
在执行multi之前,先执行watch key1 key2...;可以监视一个或者多个key,如果在事务执行前这些key被其他命令改动,那么事务会被打断。
- 取消监视unwatch
取消watch命令对所有key的监视。
如果在执行watch命令之后,exec命令或者discard命令先执行的话,就不需要再执行unwatch了。
Redis事务的三个特性
- 单独的隔离操作
事务中所有的命令都会序列化,按照顺序的执行,事务在执行过程中,不会被其他客户端发送来的命令请求打断。
- 没有隔离级别的概念
事务队列中的命令没有提交之前都不会实际执行。
- 不保证原子性
事务执行过程中如果有一条命令执行失败,其他命令仍然会被执行,不会回滚。
以上是关于redis事务和锁机制的主要内容,如果未能解决你的问题,请参考以下文章