Redis事务没有事务隔离的级别。

但是Redis事务的本质是:将一组操作放入队列(先进先出)中,批量执行。

关系型数据库的事务是:将事务操作(DML)语句写入日志。

事务相关的命令

  • Multi:开启事务
  • Exec:执行事务
  • Discard:终止事务

说明:Exec之前的事务操作可以被discard终止 但是一旦exec 本次事务就会执行!

如果一次事务操作的组队过程中出现的错误(如 正确命令是set money 100 你写成了 sett money 100),本次事务的所有命令都不会执行!!

Redis不保证原子性,Exec程序执行过程,某命令出错(比如数据库只允许存入数字,但你插入了字符),错误代码不执行,其余的正常代码依旧可以正常执行!

Redis 如何实现事务呢?

  1. 开启一个队列
  2. 让命令进入队列
  3. 执行事务
# 1 开启事务
multi

# 2 输入命令
set k1 v1
set k2 v2
get k2
set k2 v3
get k2

# 3 执行/放弃事务 (如果任何命令输错了,所有命令就不会执行,并且放弃事务!)
exec 或者 discard

Redis 悲观锁

效率低,所有悲观锁都不建议使用

悲观锁:每次都会操作都会上锁,执行完毕就会释放锁,别人才可以获得锁。这样会导致效率低下,降低并发量。

Redis CAS乐观锁 watch操作

乐观锁,任何人操作都不上锁,但是真实操作时,如果这个key发现version变动了,本次修改的相关事务操作不会执行!所有人都可以拿到锁,就可以提高系统吞吐量

Redis 乐观锁的使用场景是:电影院购票,比如C1这个作为有多人同时去抢,这张票只能被一个人抢成功。使用Redis乐观锁的好处是。抢的时候,先锁一下这个C1座位,等于被我预定了,如果发现C1被别人抢走了,本次事务将不会执行。

# 先创建一个key money = 100
set money 100

# watch 就是乐观锁 注意 watch一定要在一个线程的事务之前!!!
watch 需要锁Key名


# 线程1 操作:开启事务,并设置money为80 但不执行事务
multi
set money 80 或者 decrby money 20

# 线程2 操作:读取money 设置money 为120
get money
set money 120  或者 incrby money 20

# 线程1 执行事务
exec

# 一个线程 watch 并执行事务 失败时,一定要unwatch
unwatch

最后的结果是nil ,说明乐观锁生效了!

原理分析:

一个事务占着一个A线程执行操作时:发现被另一个B线程修改了相关的内容,就会导致乐观锁执行!导致事务A操作不会执行。

发表评论

您的电子邮箱地址不会被公开。