您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

Redis的事务实例分析

2024/3/22 7:28:45发布25次查看
redis 中的使用redis 通过 multi,exec,discard,watch 实现事务功能。
multi:开始事务
exec:提交事务并执行
discard:取消事务
watch:事务开始之前监视任意数量的键
> multiok> set bookname "redis"queued> get booknamequeued> sadd tag "redis" "new book"queued> smembers tagqueued> exec1) ok2) "redis"3) (integer) 24) 1) "redis" 2) "new book"
开始事务> multiok
这个命令将 redis_multi 选项打开,让客户端从非事务状态变为事务状态
命令入队> set bookname "redis"queued> get booknamequeued> sadd tag "redis" "new book"queued> smembers tagqueued
redis命令不会立即执行,而是先进入一个先进先出的事务队列,直到事务被提交。queued 表示这个命令已经入了事务队列。
执行事务> exec1) ok2) "redis"3) (integer) 24) 1) "redis" 2) "new book"
当执行 exec 命令时,redis 根据客户端所保存的事务队列, 以先进先出的方式执行事务队列中的命令:最先入队的命令最先执行, 而最后入队的命令最后执行。执行 exec 命令后,redis 将结果存储在回复队列中并将该队列发送给客户端。客户端从事务状态退出,一个事务执行完毕。
discard 命令> multiok> set author "lisi"queued> discardok> get author(nil)
discard 取消一个事务的命令,表示这个事务被取消。当客户端结束事务状态,回到非事务状态时,需要关闭 redis_multi 选项。
watch 命令# redis 客户端1> watch letterok> multiok> set letter aqueued> exec(nil)# redis 客户端2> set letter bok# redis 客户端1> get letter"b"
在客户端1进入事务时,监控设置了letter键,并将其值设置为a,但该事务尚未提交。客户端2设置 letter 的 value 为 b。客户端1提交事务后返回的结果为 nil,但调用 get 命令可以得到 letter 的值为 b。这意味着当 letter 键被其他客户端改变后,事务将被取消,不会执行,并返回失败。
watch 命令在事务开始之前监视任意数量的键:当调用 exce 命令执行事务时,如果任意一个被监视的键已经被其他客户端修改了,那么整个事务不再执行,直接返回失败。
事务异常命令错误> set letter acqueued> get letter ac(error) err wrong number of arguments for 'get' command> exec(error) execabort transaction discarded because of previous errors.
事务中命令异常属于语法错误,将导致事务无法执行。
运行时异常> multiok> lpush books "redis"queued> incr booksqueued> lpush books "python"queued> lrange books 0 -1queued> exec1) (integer) 12) (error) wrongtype operation against a key holding the wrong kind of value3) (integer) 24) 1) "python" 2) "redis"
上面的例子是事务执行到中间遇到失败了,因为不能对一个字符串进行 incr 命令,事务在遇到命令执行失败后,后续的命令还继续执行,所以 books 的值能继续得到设置。这种异常只有程序员在代码中避免。
事务的 acid原子性原子意味着要么一起成功执行,要么一起失败回滚。redis 提供的所有 api 都是原子操作。那么 redis 事务只要保证在一批操作中保证原子性,但是在运行时异常中,在一个事务中一个命令出现异常,其他命令还是会继续执行,事务没有回滚机制,所以 redis 事务是不保证原子性的。
一致性事务异常
如果命令错误事务无法执行,如果是运行时异常,redis 会将错误包含在返回结果中,并不影响后续执行,所以事务是一致性的。
redis 进程被终结
在纯内存模式下,redis 没有做持久化,重启之后数据库是空白的,所以是事务一致性的。
在 rdb 模式下,事务并不会在中途执行保存 rdb 文件的工作,只有在事务执行完后,rdb 工作才可能会开始。所以在事务执行过程中 redis 进程被杀死,不管成功多少都不会保存到 rdb 文件中,所以是一致性的。
在 aof 模式下,事务部分语句被写入 aof 文件并保存成功,不完整的事务被保存到了 aof 文件,当重启 redis 时,检查 aof 文件不完整,redis 退出并报错。需要把这段不完整的事务删除后才能重启成功,所以是一致性的。
在 aof 模式下,事务并未被写入 aof 文件,所以重启后 redis 数据库是最近一次成功保存到 aof 文件中的数据。并没有这次事务的数据,所以是以一致性的。
隔离性redis 是单进程程序,并且它保证在执行事务时,不会对事务进行中断,事务可以运行直到执行完所有事务队列中的命令为止。所以事务是带有隔离性的。
持久在纯内存模式下,事务肯定不是持续性的。
在 rdb 模式下,服务器可能在事务执行之后、rdb 文件更新之前的这段时间失败,所以 rdb 模式下的事务也是不持久的。
在 aof 模式下,将命令添加到 aof 文件中,但是对文件进行写入并不会马上写到磁盘上,而是先存储到缓冲区。所以数据保存到磁盘上有一段非常小的时间间隔。这种模式下事务也不是持久的。
以上就是redis的事务实例分析的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product