15

Redis之Redis事务

 3 years ago
source link: http://www.uml.org.cn/sjjm/202010202.asp?artid=23826
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
编辑推荐:

本文主要介绍了Redis事务的概念、Redis不保证原子性、Redis事务的三个阶段、Redis事务相关命令以及Redis事务使用案例。

本文来自于博客园,由火龙果软件Anna编辑、推荐。

Redis事务的概念:

Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。

总结说:redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。

Redis事务没有隔离级别的概念:

批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。

Redis不保证原子性:

Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。

Redis事务的三个阶段:

开始事务

命令入队

执行事务

Redis事务相关命令:

watch key1 key2 ... : 监视一或多个key,如果在事务执行之前,被监视的key被其他命令改动,则事务被打断 ( 类似乐观锁 )

multi : 标记一个事务块的开始( queued )

exec : 执行所有事务块的命令 ( 一旦执行exec后,之前加的监控锁都会被取消掉 )

discard : 取消事务,放弃事务块中的所有命令

unwatch : 取消watch对所有key的监控

Redis事务使用案例:

(1)正常执行

b2a6VbY.png!mobile

(2)放弃事务

Bz2QNfE.png!mobile

(3)若在事务队列中存在命令性错误(类似于java编译性错误),则执行EXEC命令时,所有命令都不会执行

Rbum22A.png!mobile

(4)若在事务队列中存在语法性错误(类似于java的1/0的运行时异常),则执行EXEC命令时,其他正确命令会被执行,错误命令抛出异常。

MNRnUjn.png!mobile

(5)使用watch

案例一:使用watch检测balance,事务期间balance数据未变动,事务执行成功

aaInayj.png!mobile

案例二:使用watch检测balance,在开启事务后(标注1处),在新窗口执行标注2中的操作,更改balance的值,模拟其他客户端在事务执行期间更改watch监控的数据,然后再执行标注1后命令,执行EXEC后,事务未成功执行。

m2MVNfj.png!mobile

R73iyuA.png!mobile

一但执行 EXEC 开启事务的执行后,无论事务使用执行成功, WARCH 对变量的监控都将被取消。

故当事务执行失败后,需重新执行WATCH命令对变量进行监控,并开启新的事务进行操作。

总结:

watch指令类似于乐观锁,在事务提交时,如果watch监控的多个KEY中任何KEY的值已经被其他客户端更改,则使用EXEC执行事务时,事务队列将不会被执行,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK