redis事务transition、乐观锁multi、watch

事务transition

Redis事务的本质是一组命令的集合,一次执行多个指令,事务中所有命令都被序列化,其他客户端提交的命令请求不会插入到事务执行命令序列中

顺序、排他、一次性

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

  • 开启事务(multi)
  • 命令入队(。。。)
  • 执行事务(exec)
  • 取消事务(discard)
  • 监视、加锁(watch)
  • 取消监视、解锁(unwatch)

乐观锁应该适用于读多写少的情况,悲观锁应该适用于写多读少的情况

悲观锁

  • 为了避免其他人同时修改,直接对数据进行加锁以防止并发,修改数据前锁定,修改的方式被称为悲观并发控制 Pessimistic Concurrency Control 悲观、并发、控制
  • 独占性、排他性
  • image-20201122194314577
  • 在整个数据处理过程中,数据处于锁定状态
  • 线程操作数据,对数据添加排他锁
  • 假设最坏的情况,每次都默认其他线程更改数据
  • 传统数据库使用的几种加锁机制,都是在操作之前上锁
    • 行锁
    • 表锁
    • 读锁
    • 写锁
  • 在Java中同步用synchronized关键字实现
  • 悲观锁住要分共享锁和排他锁
    • 共享锁 shared locks
      • 读锁、S锁,多个事务对同一个数据可以共享一把锁,都能访问数据,只能读不能修改
    • 排他锁 exclusive locks
      • 写锁、X锁、不能与其他锁并存,一个事务获取了数据行的排他锁,其他事物就不能再获得该行的其他锁,获取排他锁的事物可以对数据行读取和修改
  • 悲观并发控制 先取锁再访问 的保守策略,开销大,还增加死锁的概率,降低并发性,其他事务必须等待

乐观锁

  • 假设数据一般情况不会造成冲突,在数据提交更新时正式对数据的冲突与否进行检测,发现了冲突,发出错误信息,让用户决定如何处理,适用于读操作多的场景,可以提高程序的吞吐量
  • 为了避免数据库的幻读,业务处理时间过长,乐观锁不会刻意使用数据库本身的锁机制,而是一句数据本身来保证数据的正确性
  • image-20201122194339249
  • 实现方法
    • CAS实现:java.util.concurrent.atomic 包下的原子变量
    • 版本号控制,在数据表添加爱version字段,数据被修改时,version值+1,线程更新数据,同时读取version值,提交更新时,读取到的version值与当前数据库中的version值相等才更新,否则重试,直到更新成功
multi实现
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1 k2 v2
QUEUED
127.0.0.1:6379> getget k1
(error) ERR unknown command `getget`, with args beginning with: `k1`, 
127.0.0.1:6379> 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> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> mset k1 test k2 v2
QUEUED
127.0.0.1:6379> incr k1
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) "v2"
4) OK
5) "v3"
127.0.0.1:6379> #出现执行中产生的错误,能正确入队,不会影响到其他命令的执行
watch监视实现
  • 当有多个线程在操控redis的时候

  • 被watch监视的key值如果发生改变,正在进行的事务将会失败

  • 每次加锁后都要进行解锁,再加锁去重新获取最新的值

  • 线程1

    • 127.0.0.1:6379> watch key
      OK
      127.0.0.1:6379> set key1 10
      OK
      127.0.0.1:6379> multi
      OK
      127.0.0.1:6379> incrby key 10
      QUEUED
      127.0.0.1:6379> incrby key1 20
      QUEUED
      127.0.0.1:6379> exec
      (nil)
      127.0.0.1:6379> mget key key1
      1) "30"
      2) "10"
      127.0.0.1:6379> #对key进行监控,key被阻止事务更新,key1在事务中也无法更新
      
  • 线程2

    • 127.0.0.1:6379> set key 30
      OK
      127.0.0.1:6379> #在线程1进行事务时,watch之后 exec之前,执行了set操作,会导致线程1的事务执行失败
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
悲观锁和乐观锁是在数据库操作中常见的两种并发控制机制,而Redis也提供了乐观锁的实现方式。 悲观锁是一种悲观的思想,每次在获取数据之前都会认为其他人会修改数据,所以在获取数据时就会上锁,其他人需要等待直到锁被释放才能获取数据。传统的关系型数据库中常用的行锁、表锁等都属于悲观锁的实现方式。悲观锁适用于对数据的强一致性要求较高的场景,但效率相对较低,特别是在读的并发较高的情况下。 乐观锁则是一种乐观的思想,认为在大多数情况下并发冲突是较少发生的,所以在读取数据时不会立即上锁。而是在更新数据时会先检查数据是否被其他人修改过,如果没有则更新成功,如果有则需要进行重试或者放弃操作。乐观锁适用于读多写少,并发冲突较少的场景。在Redis中,可以使用watch机制实现乐观锁。 总的来说,乐观锁适用于并发冲突较少的情况下,可以减少锁的开销,提高系统的吞吐量。而悲观锁适用于并发冲突较多的情况下,可以保证数据的强一致性。在Redis中,可以根据实际场景选择使用悲观锁还是乐观锁。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [大数据之Redis:悲观锁和乐观锁](https://blog.csdn.net/weixin_43597208/article/details/118465556)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Redis中的乐观锁和悲观锁](https://blog.csdn.net/qq_39612954/article/details/107470999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值