Redis事务和锁的应用详解

一、Redis事务的应用

无论是大小项目还是各种系统,相信事务是不容忽视的,下面,我们对redis的事务展开讨论。

如果你比较熟悉mysql的事务,redis的事务那就很简单了。我们对redis的事务和mysql的事务进行下比较就能更清楚的了解到redis的事务机制了。
这里写图片描述

通过比较,我们可以清楚的看到redis的事务命令,先看一段mysql的事务。

start transaction;   -- 开启事务
update user set money=money-100 where id=1;
.......
commit;   --提交事务

上面是段简单的mysql事务处理的代码,通过这段代码我们可以和上面的redis进行比较轻松的掌握redis怎么启动事务并且如何工作。

redis启动事务:

multi

当我们通过上面命令启动事务后,我们就可以根据用户的操作对事务进行处理。
如果想回滚事务(redis中准确的说是取消事务),可以用下面命令:

discard

如果想提交事务:

exec

那么,redis中事务是怎样工作的呢?首先来一个简单的实例:

这里写图片描述
这里,我么看到了一个很奇怪的问题,当我们启动事务后,然后进行我们的操作,比如我们设置李四的账户有300块钱(set lisi:money 300)当我们按回车键的时候,返回一个QUEUED,是队列的意思,这是为什么呢?这就是我们要讲的在redis中它会用一个队列来保存用户的事务操作,当你exec提交事务后它会按照顺序来执行每一条语句。这里,值得注意的是,当你启动事务,每执行一个操作,它并不是真正的执行,而是暂时放在这个队列中,等待事务的提交。如果在提交事务后执行时中间有一个语句出错会怎么样?

这里有两种情况。
1.语句有语法错误,它会将所有的事务取消。
这里写图片描述

2: 语法本身没错,但适用对象有问题. 比如 zadd 操作list对象,Exec之后,会执行正确的语句,并跳过有不适当的语句.(如果zadd操作list这种事怎么避免? 这一点,由程序员负责)

简单介绍完redis的事务,接着就是与事务密不可分的锁了。下面我们来讨论redis中的锁应用。

二、redis中锁的讲解及应用

说到锁,大家都知道有很多锁,比如乐观锁,悲观锁,排它锁,共享锁等等。
这里我们简单所以下乐观锁和悲观锁。

乐观锁

在关系数据库管理系统里,乐观并发控制(又名“乐观锁”,Optimistic Concurrency Control,缩写“OCC”)是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。

悲观锁

在关系数据库管理系统里,悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作都某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。
悲观并发控制主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中。

上面对于乐观锁和悲观锁的介绍如果大家理解困难的话,我们可以这样通俗简单的理解,对于乐观锁,就像一个人的情绪上很乐观,就好像你要买车票,你总感觉车票还是会有的,你只要在你支付车票费用的时候 观察一个是否还有车票,如果有就进行支付,如果没有就进行回滚之前的操作。对于悲观锁,一个处理事情比较悲观,它很担心会没有车票,以最坏的情况讨论,所以它买票之前对车票进行全程的 监控,一旦没有票就回退操作(在真正的事务处理中,它会对事务上锁,不允许其他进程操作该事物,直到释放该锁)。

在redis中,它默认使用的是乐观锁。只负责监控key是否被改动。
我们来看两个例子:

multi
set lisi:money 300
set ticket 1

上面代码,我们设置了李四有300块钱,还有一张机票,李四要买这张机票,假设这时有一个比他速度快,先抢到了这张票(启动另外一个进程)。

decr ticket

这是如果李四继续买票会发生什么情况呢?

decrby lisi:money 200
decr ticket
exec

如果只是单单上面的代码,我们会发现ticket变为-1,这是绝对不允许发生的,该怎么办呢?这是就要用到redis的乐观锁,它使用watch命令监控指定key,如果key被改动了,当我们提交事务后,如果发生异常就会取消当前事务,所以我们只需在上面代码中开启事务前加入watch语句就可以避免上面的问题了。

watch ticket

当然,watch也可以简单是多个key

watch key1 key2 key3...

也可以通过unwatch命令取消对key的监控

unwatch key..
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值