Redis事务

目录

redis中的事务

redis中事务的命令

开启事务MULTI,执行事务EXEC,放弃当前事务DISCARD

watch命令


redis中的事务

redis的事务和mysql的事务概念上是类似的,都是把一系列操作打包成一组,让这一组操作能够批量执行.

mysql的事务涉及四个特性,原子性,一致性,持久性和隔离性.

redis事务和mysql事务的区别:

  • 弱化的原子性:redis没有回滚机制,只能做到这些操作批量执行,不能做到"一个命令执行失败就恢复到初始状态".简单说就是可以打包但是不保证都能执行成功.
  • 不具备一致性:redis中没有约束,也没有回滚机制,在事务执行的过程中如果某个修改操作出现失败,就可能引起数据不一致(数据非法)的情况.mysql的一致性体现在运行事务前和运行后,结果都是合理有效的,不会出现中间非法状态,这一点redis是做不到的.
  • 不具备持久性:redis本身就是内存数据库,数据都是存储在内存中的.虽然redis有持久化机制,但是持久化机制和事务没有关系.
  • 不涉及隔离性:也没有隔离级别,redis是一个单线程的服务器程序,所有的请求/事务都是串行执行的,所以不涉及隔离性.

综上,redis事务主要的意义就是为了"打包",避免其他客户端的命令,插队执行.

redis事务本质上是在服务器这里创建了一个事务队列,每次客户端在事务中进行一个操作,都会先把命令放到事务队列当中,并不会立即执行.当服务器收到此客户端的执行事务的命令之后,才会真正执行队列中的所有操作.(事务队列对应每一个客户端都会有一个).

因此redis的事务功能相对于mysql来说,是弱化了很多的.只能保证事务中的这几个操作是连续的,不会被别的客户端插队.

redis如果是按照集群模式部署的,是不支持事务的!!


redis中事务的命令

开启事务MULTI,执行事务EXEC,放弃当前事务DISCARD

事务演示

Redis事务_第1张图片

每次添加一个操作,都会提示QUEUED,说明命令已经进入服务器的队列了,真正执行exec的时候,服务器才会执行事务队列中的命令.

开启事务后,命令不会立即执行,此时,查询key是查询不到的.

Redis事务_第2张图片

直到我们真正的执行事务之后,才会执行事务中的命令.

Redis事务_第3张图片

在开启事务后,执行discard命令会放弃当前的事务.

Redis事务_第4张图片

当开启事务后,并且给服务器发送若干命令之后,此时服务器重启,那么这个事务的效果就等同于执行了discard.


watch命令

在执行事务的时候,如果某个事务中修改的值,被别的客户端修改了,此时就容易出现数据不一致的问题.

watch命令的作用就是监控某个key是否在事务执行之前发生了改变.

Redis事务_第5张图片

从输入命令的时间看,是客户端1先执行的set key 100,客户端2后执行的set key 200,但是从实际的执行时间看,是客户端2先执行的,客户端1后执行的,这时就很容易引起歧义,因此即使不保证严格的隔离性,但至少也要告诉用户,当前的操作是有可能存在风险的.

watch就是用来解决上述问题的.

• 当开启事务的时候, 如果对 watch 的 key 进⾏修改, 就会记录当前 key 的 "版本号". (版本号是个简单的整数, 每次修改都会使版本变⼤. 服务器来维护每个 key 的版本号情况)
• 在真正提交事务的时候, 如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号, 就会让事务执⾏失败. (事务中的所有操作都不执行)

unwatch命令表示取消对key的监控.

你可能感兴趣的:(redis,redis,数据库,缓存)