Redis:事务操作以及监控(悲观锁,乐观锁)

这篇具有很好参考价值的文章主要介绍了Redis:事务操作以及监控(悲观锁,乐观锁)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是事务?

事务操作是指:在一组操作中,有很多的命令,如果在这组操作时,有一个命令出现的了bug,那么这组这组操作会进行回滚,将环境还原成没有开始这组操作时的状态。在MySQL等关系型数据库中事务操作可能会出现这种结果,但是在redis则也可能出现其他的错误,那就是语法问题,通俗的讲就是在MySQL数据库中实现转账业务,一个人的金额增加,一个人减少,如果失败那么两人就不会有任何变化,但是在redis则不同,它也有可能出现,一个人的金额增加,但是另外的哪一个人金额并没有减少,下面会讲到。

事务操作支持多项命令,命令会被序列化,通俗的来讲就是命令会被放入一个队列中。

在事务操作过程中,执行步骤会按照队列中的顺序进行执行,队列之外的命令并不会插入执行事务操作执行命令的过程中。

单一的命令执行保持原子性,但是事务操作却不会保持原子性,就是要么成功的执行全部,要么则是白用功,回到故事的开端,重新开始。

在redis中执行事务

注意:开启事务后,会出现 TX 标志,此时所有的操作不会马上有结果,而是形成队列(QUEUED),待执行事务后,会将所有命令按顺序执行。

开启事务

127.0.0.1:6379> FLUSHALL      清空redis数据库             
OK
127.0.0.1:6379> MULTI               开启事务操作
OK
127.0.0.1:6379(TX)> set key1 v1       命令,但不是直接执行,这项命令会被放到队列中
QUEUED
127.0.0.1:6379(TX)> set key1 v2
QUEUED
127.0.0.1:6379(TX)> set key2 v1
QUEUED
127.0.0.1:6379(TX)> get key2
QUEUED
127.0.0.1:6379(TX)> set key3 v3
QUEUED
127.0.0.1:6379(TX)> exec         执行队列中命令,就是前面的几行命令
1) OK                                         这是执行命令中的结果                                          

2) OK
3) OK
4) "v1"
5) OK
127.0.0.1:6379> keys *     命令执行成功
1) "key3"
2) "key2"
3) "key1"
127.0.0.1:6379> 

 放弃事务:DISCARD

127.0.0.1:6379> FLUSHALL
OK 
127.0.0.1:6379> MULTI                  开启事务                                     
OK
127.0.0.1:6379(TX)> set key1 v1    
QUEUED
127.0.0.1:6379(TX)> set key2 v2
QUEUED
127.0.0.1:6379(TX)> set key3 v3
QUEUED
127.0.0.1:6379(TX)> DISCARD     取消事务
OK
127.0.0.1:6379> keys *           事务并没有执行,取消成功
(empty array)
127.0.0.1:6379> 

事务中的命令存在错误:编译性错误

127.0.0.1:6379> MULTI         
OK
127.0.0.1:6379(TX)> set key1 v1                      创建一个key,加入到队列当中
QUEUED
127.0.0.1:6379(TX)> getset key1                      错误的命令
(error) ERR wrong number of arguments for 'getset' command     报错
127.0.0.1:6379(TX)> set key2 v2                      再创建一个key,加入到队列当中
QUEUED
127.0.0.1:6379(TX)> exec                                执行事务操作
(error) EXECABORT Transaction discarded because of previous errors.   报错
127.0.0.1:6379> keys *                                     事务中的所有命令,都没有被执行
(empty array)
127.0.0.1:6379> 

运行错误:加入队列中命令没有问题,但是执行命令可能存在一些语法性的问题,这时队列中的问题依旧会被执行,这个问题就是我在上面提到的转账业务,一个人会增加,但是另外一个人却不一定会减少。

127.0.0.1:6379> FLUSHALL
OK
127.0.0.1:6379> set key1 v1     创建一个key
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> INCR key1   让先前创建的key+1,但是因为创键的key1是字符串,所以此代码执行可能会报错,但是这行代码在语法是没有错误,它能正常的添加到队列中。
QUEUED                                        添加成功
127.0.0.1:6379(TX)> set key2 v2   创建几个其他的可以
QUEUED
127.0.0.1:6379(TX)> get key2
QUEUED
127.0.0.1:6379(TX)> EXEC          执行队列中的方法
1) (error) ERR value is not an integer or out of range  队列的第一条命令报错
2) OK                                                                            其他的命令正常执行
3) "v2"
127.0.0.1:6379>  

监控:watch

乐观锁:

        乐观主义者,认为数据并不会出现问题,并不会进行上锁,在更新数据时,要与监控时数据进行比较,如果有人更改数据,则数据并不会发生改变。

        获取version

        在执行操作命令时去比较version时候发生改变

悲观锁:

        悲观主义者:认为数据无论在什么时候都有可能出现问题,什么数据都上锁 

redis测试监控

正常情况下

127.0.0.1:6379> FLUSHALL 
OK
127.0.0.1:6379> set money 100    设置初始值
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money   对money进行监控
OK
127.0.0.1:6379> MULTI                  开启事务
OK
127.0.0.1:6379(TX)> DECRBY money 10   减少10
QUEUED
127.0.0.1:6379(TX)> INCRBY out 10        增加10
QUEUED
127.0.0.1:6379(TX)> EXEC                   执行队列命令,并不会发生任何问题,正常执行
1) (integer) 90
2) (integer) 10
127.0.0.1:6379> 

 在多线程环境里出现乐观锁时

线程一:

127.0.0.1:6379> WATCH money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> INCRBY out 50
QUEUED
127.0.0.1:6379(TX)> DECRBY money 50
QUEUED
127.0.0.1:6379(TX)> get money
QUEUED

当线程一正在执行事务时这是线程二介入修改了money的数据值 

线程二:

127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> 

那么线程一执行事务,会出现怎样的结果呢?

127.0.0.1:6379> WATCH money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> INCRBY out 50
QUEUED
127.0.0.1:6379(TX)> DECRBY money 50
QUEUED
127.0.0.1:6379(TX)> get money
QUEUED
127.0.0.1:6379(TX)> EXEC             队列中命令全都执行失败
(nil)
127.0.0.1:6379>  

出现乐观锁问题,之后又如何执行完线程一的操作呢?

127.0.0.1:6379> unwatch           首先先解锁
OK
127.0.0.1:6379> WATCH money 然后再上锁
OK
127.0.0.1:6379> MULTI                开启事务操作
OK
127.0.0.1:6379(TX)> DECRBY money 50
QUEUED
127.0.0.1:6379(TX)> INCRBY out 50
QUEUED
127.0.0.1:6379(TX)> get money
QUEUED
127.0.0.1:6379(TX)> EXEC                  执行,成功
1) (integer) 50
2) (integer) 60
3) "50"  
127.0.0.1:6379>  文章来源地址https://www.toymoban.com/news/detail-445990.html

到了这里,关于Redis:事务操作以及监控(悲观锁,乐观锁)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (学习笔记-进程管理)什么是悲观锁、乐观锁?

    最底层的两种就是 [互斥锁和自旋锁],有很多高级的锁都是基于它们实现的。可以认为它们是各种锁的地基,所以我们必须清楚它们之间的区别和应用。 加锁的目的就是保证共享资源在任意时间内,只有一个线程访问,这样就可以避免多线程导致共享数据错乱的问题。 当已

    2024年02月11日
    浏览(40)
  • redis乐观锁+启用事务解决超卖

    乐观锁用于监视库存(watch),然后接下来就启用事务。 启用事务,将减库存、下单这两个步骤,放到一个事务当中即可解决秒杀问题、防止超卖。 但是!!!乐观锁,会带来\\\" 库存遗留 问题\\\" ,这个时候可以通过LUA脚本解决。

    2024年02月11日
    浏览(34)
  • Redis-redis事务、乐观锁、Jedis、SpringBoot整合Redis

    1、事务 ①开启事务、执行事务 ② 取消事务 ③ 编译性异常(代码有问题! 命令有错!),事务中所有的命令都不会被执行! ④ 运行时异常(I/O),如果事务队列中存在语法行,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常! (区别于直接命令错误

    2024年01月16日
    浏览(41)
  • pipeline、lua、redis事务以及操作springboot操作redis的一些学习以及思考

    ai答:在使用 Jedis 进行 Redis 操作时,调用 jedis.close() 的目的是释放与 Redis 服务器的连接并关闭 Jedis 实例,以便释放资源并确保连接的正确关闭。 具体原因如下: 资源释放:调用 jedis.close() 方法会自动释放 Jedis 实例占用的资源,包括网络连接、线程资源等。如果不调用 cl

    2024年02月13日
    浏览(36)
  • 悲观锁&乐观锁

    1.悲观锁 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层

    2024年02月08日
    浏览(32)
  • [锁]:乐观锁与悲观锁

    摘要:乐观锁;悲观锁;实现方法;本地锁;分布式锁;死锁;行级锁;表级锁 问题 : ① 在多个线程访问共享资源时,会发生线程安全问题,例如:在根据订单号生成订单时,若用户第一次由于某种原因(网络连接不稳定)请求失败,则会再次发生请求,此时便会产生同一

    2024年02月08日
    浏览(34)
  • 悲观锁和乐观锁(易懂)

    这里可以把悲观锁看作悲观的人,啥事都往最坏的方向想。乐观锁看作乐观的人,啥事都往最好的方向想。 首先,说一下悲观锁。 悲观锁就是假设并发情况下一定会有其他线程来修改数据,因此在处理数据之前,先将数据锁住,确保其他线程不能进行修改 。感觉像一个过于

    2024年02月08日
    浏览(36)
  • django实现悲观锁乐观锁

    前期准备 1.原生mysql悲观锁 2.orm实现上述(悲观锁)  3 乐观锁秒杀--》库存还有,有的人就没成功  

    2024年02月12日
    浏览(39)
  • 悲观锁和乐观锁、缓存

    悲观锁: 悲观锁的实现通常依赖于数据库提供的机制,在整个处理的过程中数据处于锁定状态,session的load方法有一个重载方法,该重载方法的第三个参数可以设置锁模式,load(object.class , int id,LockMode.?),该方法的?就是具体的锁模式。 乐观锁: 乐观锁使用版本号或者时间戳

    2024年02月09日
    浏览(41)
  • MySQL乐观锁与悲观锁

    遇见并发情况,需要保证数据的准确性,也就是与正确的预期一致,此时就会用到锁。 锁是在并发下控制程序的执行逻辑,以此来保证数据按照预期变动。 如果不加锁,并发情况下的可能数据不一致的情况,这是个概率问题。 乐观锁很乐观,假设数据一般情况不会造成冲突

    2024年01月23日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包