当前位置: 首页 > 科技观察

一篇文章可以学习的Redis事务

时间:2023-03-12 05:57:23 科技观察

大家好,我是北君。Redis作为一个内存存储中间件,已经是面试必问的面试题之一了。今天我们就来看看Redis的事务。事务提供了一种“打包多个命令,一次提交,顺序执行”的机制。提交后,交易执行不会中断。来自其他客户端的消息只有在执行完所有命令后才会继续。在Redis中使用Redis,通过multi、exec、discard、watch实现事务功能。multi:启动事务exec:提交事务并执行discard:取消事务watch:在事务开始前观察任意数量的键>multiOK>setbookName"Redis"QUEUED>getbookNameQUEUED>saddtag"Redis""NewBook"QUEUED>smemberstagQUEUED>exec1)OK2)"Redis"3)(integer)24)1)"Redis"2)"NewBook"开始一个事务>multiOK这个命令开启Redis_multi选项,允许客户端从非事务状态到事务状态。team>setbookName"Redis"QUEUED>getbookNameQUEUED>saddtag"Redis""NewBook"QUEUED>smemberstagQUEUED在事务状态下,Redis命令不会立即执行,而是进入一个先进先出的事务队列。QUEUED指示此命令已进入事务队列。Executiontransaction>exec1)OK2)"Redis"3)(integer)24)1)"Redis"2)"NewBook"在执行exec命令时,Redis会根据事务采用先进先出的方式客户端保存的队列执行事务队列中的命令:第一个排队的命令最先执行,最后一个排队的命令最后执行。当执行exec命令时,Redis会将结果保存到一个回复??队列中,并将回复队列返回给客户端。客户端退出事务状态,执行事务。discardcommand>multiOK>setauthor"lisi"QUEUED>discardOK>getauthor(nil)discard取消交易的命令,表示交易被取消。客户端退出事务状态,返回非事务状态,关闭Redis_multi选项。watchcommand#Redisclient1>watchletterOK>multiOK>setletteraQUEUED>exec(nil)#Redisclient2>setletterbOK#Redisclient1>getletter"b"setmonitorletterkey,客户端1进入事务,设置字母a的值,事务未提交。客户端2将字母的值设置为b。回到客户端1,提交交易返回的结果为nil,调用get命令获取字母为b。这意味着当字母键被其他客户端更改时,交易被取消,不会被执行,返回失败。watch命令在事务开始前监听任意多个key:调用exce命令执行事务时,如果监听到的任意一个key被其他客户端修改,则整个事务不会执行,失败直接退回。事务异常命令错误>setletteracQUEUED>getletterac(error)ERRwrongnumberofargumentsfor'get'command>exec(error)EXECABORT事务因先前的错误而被丢弃。事务中的命令异常是语法错误,会导致事务无法执行。运行时异常>multiOK>lpushbooks"Redis"QUEUED>incrbooksQUEUED>lpushbooks"Python"QUEUED>lrangebooks0-1QUEUED>exec1)(integer)12)(error)WRONGTYPEOperationagainstakeyholdingawrongkindofvalue3)(integer)24)1)"Python"2)"Redis"上面的例子是事务在执行中途失败,因为incr命令无法对字符串执行,事务遇到命令执行失败后,后续命令继续执行,所以可以继续设置books的值。这种异常只有程序员在代码中才能避免。ACID事务的原子性原子意味着要么全部一起成功,要么全部失败并回滚。Redis提供的所有API都是原子操作。那么Redis事务只需要在一批操作中保证原子性即可,但是在运行时异常情况下,如果一个事务中的一条命令出现异常,其他命令会继续执行。事务没有回滚机制,所以Redis事务不保证原子性。性的。一致性事务异常如果命令错误事务无法执行,如果是运行时异常,Redis会将错误包含在返回结果中,不会影响后续执行,所以事务是一致的。Redis进程在纯内存模式下终止。Redis不是持久化的。重启后,数据库是空白的,所以是事务一致的。在RDB模式下,事务不会在中间执行保存RDB文件的工作,RDB的工作只有在事务执行完后才会开始。因此,如果Redis进程在事务执行过程中被kill掉,不管再成功,也不会保存到RDB文件中,所以是一致的。在AOF模式下,部分事务语句被写入AOF文件并保存成功,未完成的事务被保存到AOF文件中。重启Redis时,检查AOF文件是否不完整,Redis退出报错。这个不完整的事务需要删除才能重启成功,所以是一致的。AOF模式下,事务不会写入AOF文件,所以重启后,Redis数据库是最新成功保存到AOF文件的数据。这个交易没有数据,所以是一致的。隔离Redis是一个单进程程序,保证事务在执行的时候不会被打断,直到事务队列中的所有命令都执行完,事务才能运行。所以交易是隔离的。持久化在纯内存模式下,事务肯定不是持久化的。RDB模式下,在事务执行后到RDB文件更新前的这段时间,服务器可能会发生故障,所以RDB模式下的事务是不持久的。在AOF模式下,命令被添加到AOF文件中,但是写入文件不会立即写入磁盘,而是先存储到缓冲区中。所以数据保存到磁盘的时间间隔非常短。这种模式下的交易也不持久。结束语本文介绍了Redis事务的multi、exec、discard、watch命令用法及其ACID。