redis的事务和锁

redis的事务

  • redis没有隔离级别的概念
  • redis的单条指令是原子性的,但是事务不保证原子性

redis的事务:

1、开启事务multi
2、命令入队(编写一些命令)
3、执行事务exec

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)> exec #执行事务
1) OK
2) OK

放弃事务DISCARD

127.0.0.1:6379> MULTI  #开启事务
OK
127.0.0.1:6379(TX)> set key3 v3
QUEUED
127.0.0.1:6379(TX)> DISCARD #放弃事务
OK

事务执行出现异常

  • 编译时异常(如果事务队列中一个命令编译错误,就都不执行)
127.0.0.1:6379> MULTI  #开启事务
OK
127.0.0.1:6379(TX)> set key1 v1
QUEUED
127.0.0.1:6379(TX)> setsjcs  #错误的命令
(error) ERR unknown command 'setsjcs', with args beginning with: 
127.0.0.1:6379(TX)> exec 
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get key1
(nil)  #所有的命令都不执行,之前的key1也没有设置进去


  • 运行时异常,如果事务队列中某条命令运行时异常,其他的命令是可以正常执行的
127.0.0.1:6379> MULTI #开启事务
OK
127.0.0.1:6379(TX)> set key1 "v1"
QUEUED
127.0.0.1:6379(TX)> INCR key1 #对字符串进行加一操作
QUEUED
127.0.0.1:6379(TX)> set key2 v2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) ERR value is not an integer or out of range #运行时的异常
3) OK
127.0.0.1:6379> get key1
"v1"
127.0.0.1:6379> get key2
"v2"

redis的监视(watch)

  • 悲观锁:
    很悲观,认为什么时候都会出现问题,无论干什么都要加锁。

  • 乐观锁:
    很乐观,认为什么时候都不会出问题,只有更新的时候会去判断一下此期间是否有人更改过数据

  • 先查找数据库的version字段

  • 更新时判断version是否和之前查的一致,一致就更新,不一致就不更新

监视

正常执行

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 #监视钱数的变化
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> DECRBY money 20 #总钱数减少20
QUEUED
127.0.0.1:6379(TX)> INCRBY out 20 #拿出的钱数增加20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20

当事务执行的过程中有其他的线程来修改了数据,那么就会撤销此次事务操作

127.0.0.1:6379> watch money #监视总钱数
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 20 #总钱数减20
QUEUED
127.0.0.1:6379(TX)> incrby out 20 #拿出的钱加20
QUEUED
127.0.0.1:6379(TX)> exec   #事务执行之前有人对数据进行了修改,因此事务执行失败
(nil) 

watch加锁,unwatch解锁,如果事务执行失败,就先解锁再加锁

你可能感兴趣的:(redis,redis,数据库,java)