Redis只支持简单的事务,不像mysql那样比较完整严格,对数据的完整性也维持的很好。redis的开启事务实际上只是将开启事务之后的一段命令用队列
包裹起来了,当调用redis的执行命令(exec)全部执行在队列中的命令。
一、mysql事务与redis事务的比较

 

Mysql

Redis

开启

start transaction

multi

语句

普通sql

普通命令

失败

rollback 回滚

discard 取消

成功

commit

exec

二、redis事务一般使用演示
(1).先清空所有数据
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set t1 "test1 value"
QUEUED
127.0.0.1:6379> set t2 "test2 value"
QUEUED
127.0.0.1:6379>
(2).当没有执行提交的时,打开另外一个redis命令窗口执行keys *发现并没有新的数据产生
127.0.0.1:6379> keys *
(empty list or set)
(3).在窗口一种执行提交
127.0.0.1:6379> exec
1) OK
2) OK
(4).另一窗口显示所有key
127.0.0.1:6379> keys *
1) "t1"
2) "t2"

三、redis事务若是出错并不回滚
redis事务命令列中如果出错,整个事务并不回滚,而是会继续执行下去,所以这就违反了事务中ACID特点的原子性
redis事务出错的两种情况:
(1).redis语法有问题导致出错
执行exec后的结果:所有multi后执行的命令都不会被执行

演示如下:
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a a
QUEUED
127.0.0.1:6379> set b
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
查看最终结果key:
127.0.0.1:6379> keys *
1) "t1"
2) "t2"
总结:并没有找到multi后执行的命令结果key,说明全部失败了

(2).redis语法没问题但是操作的适用对象有问题,比如sadd(设置set类型的值)操作string类型的key
执行exec的结果:除了redis语法操作的命令不被正确执行,其它不会被影响正常执行(这个是属于程序级别的出错,一般是由程序员控制的)
演示如下:
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set num1 3
OK
127.0.0.1:6379> set num2 4
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby num1 3
QUEUED
127.0.0.1:6379> sadd num2 2
QUEUED
127.0.0.1:6379> exec
1) (integer) 6
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
查看最终结果:
127.0.0.1:6379> mget num1 num2
1) "6"
2) "4"
127.0.0.1:6379>
总结:因为num1,num2都是字符串类型,multi后用sadd操作num2类型错误,而最终执行后只是num2执行失败,num2正常的由数字3增加了3变成了六。

四、redis的锁机制
悲观锁:如果我去买票,我会想世界不和谐,肯定有人跟我抢,我先把票锁起来,只有我能够操作,这就是悲观锁
乐观锁:如果我去买票,哎呀没那么多人买票,还有好多的票了,所以不用上锁,我只需要关注最后剩下多少张票就行了,这就是乐观锁
演示如下
127.0.0.1:6379> keys *
(empty list or set)
如果售票点有1张票,自己手上还有100块钱
127.0.0.1:6379> set ticket 1
OK
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> mget ticket money
1) "1"
2) "100"
我们先给ticket(票)加锁
127.0.0.1:6379> watch ticket
OK
开始执行事务
127.0.0.1:6379> multi
OK
这个时候火车站只有一张余票了,我发起了两张票的请求
127.0.0.1:6379> decrby ticket 2
QUEUED
扣除80块的票钱
127.0.0.1:6379> decrby money 80
QUEUED
开始执行提交
127.0.0.1:6379> exec
报错了
(error) EXECABORT Transaction discarded because of previous errors.
查看结果没有变化因为票只有一张不够所以整个事务保持原有的结果
127.0.0.1:6379> mget ticket money
1) "1"
2) "100"
unwatch取消所有锁监听
127.0.0.1:6379> unwatch
OK
总结:redis的事务中,启用的是乐观锁,只负责事务中key没有被改动。

最新文章

  1. SecWeek
  2. viewdata向view传递匿名类,view该如何遍历?
  3. CSS中a标签样式的“爱恨”原则
  4. Linux系统下如何修改主机名
  5. Android 使用 RemoteViews 发送自定义通知 ,遇到 Couldn't expand RemoteViews问题总结
  6. 关于fsockopen pfsockopen函数被禁用的解决方法
  7. NOI2012 Day2
  8. OpenVPN多处理之-netns容器与iptables CLUSTER
  9. [ 流行的网络框架 ] AFN & ASI
  10. 【轉】JS,Jquery获取各种屏幕的宽度和高度
  11. 04 入门 - ASP.NET MVC应用程序的结构
  12. POJ2676 Sudoku 舞蹈链 DLX
  13. php7之严格模式RFC
  14. 打印页面时a标签不显示URL的方法
  15. jqgrid 使用自带的行编辑
  16. js:Date格式化
  17. Netty源码分析第2章(NioEventLoop)---->第6节: 执行select操作
  18. lombok 介绍及基本使用方法
  19. vue中添加Echarts图表的使用,Echarts的学习笔记
  20. Andrew File System

热门文章

  1. Nginx启动/重启失败
  2. Sql server日期函数操作
  3. LeetCode OJ:Generate Parentheses(括号生成)
  4. JSP的EL和JSTL解析
  5. Azure 软件架构选择
  6. Android 框架学习2:源码分析 EventBus 3.0 如何实现事件总线
  7. Vue学习笔记 ——computed VS methods
  8. C# 超级狗 二次开发 读写数据 激活验证 存储数据库连接字符串
  9. python函数作用域
  10. wireshark的提示