Redis事务与MySQL事务 整理

14 篇文章 0 订阅
5 篇文章 0 订阅

事务:Transaction

本质是一组命令的集合,可以一次执行多个命令,所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许插队。将一组需要一起执行的命令放到multiexec两个命令之间。multi命令代表事务开始,exec命令代表事务结束,它们之间的命令是原子顺序执行的。

Redis事务的三个特性

单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断;

没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题;

不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚;

Redis事务执行的三个阶段

开启:以MULTI开始一个事务;

入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面;

执行:由EXEC命令触发事务;

正常执行
在这里插入图片描述
放弃事务
在这里插入图片描述
编译时异常
在这里插入图片描述
运行时异常
在这里插入图片描述

对比

默认状态

mysql:
mysql会默认开启一个事务,且缺省设置是自动提交,即每成功执行一次sql一个事务就会马上commit,所以不能rollback;
默认情况下如上所述,但是非默认情况下,可以rollback

redis:
redis默认不会开启事务,即command会立即执行,而不会排队,并不支持rollback

使用方式

mysql(包含两种方式):
Begin、Rollback、commit显式开启并控制一个 新的 Transaction;
执行命令 set autocommit=0,用来禁止当前会话自动commit,控制默认开启的事务;

redis
multi、exec、discard,显式开启并控制一个Transaction。(注意:这里没有强调 “新的” ,因为默认是不会开启事务的)。

实现原理

mysql:
mysql实现事务,是基于undo/redo日志;
undo记录修改前状态,rollback基于undo日志实现;
redo记录修改后的状态,commit基于redo日志实现;
在mysql中无论是否开启事务,sql都会被立即执行并返回执行结果,只是事务开启后执行后的状态只是记录在redo日志,执行commit之后,数据才会被写入磁盘

如: int insertSelective = serviceOrderMapper.insertSelective(s);

上述代码,insertSelective 将会被立即赋值(无论是否开启事务,只是结果或未被写入磁盘):

redis:
redis实现事务,是基于commands队列;
如果没有开启事务,command将会被立即执行并返回执行结果,并且直接写入磁盘;
如果事务开启,command不会被立即执行,而是排入队列,并返回排队状态(具体依赖于客户端(例如:spring-data-redis)自身实现)。调用exec才会执行commands队列

boolean a = redisTemplate.opsForZSet().add(“generalService”,orderId,System.currentTimeMillis());

上述代码,如果没有开启事务,操作被立即执行,a将会被立即赋值(true/false);
如果开启事务,操作不会被立即执行,将会返回null值,而a的类型是boolean,所以将会抛出异常:java.lang.NullPointerException;

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值