redis 的事务

redis的事务
1.事务最基本的特点?
事务是一个不可分割的操作,意思就是在执行这一连串动作的时候,中间不会被其他线程(客户端)执行的程序打断。
这个特点在关系型数据库是通用的。注意:redis是单线程运行的,所有的指令均是单线程逐个被执行。
2.redis事务所涉及到的几个命令
1)加锁的命令
watch:用在multi命令之前,对任何key都可以加锁,语法watch key1 key2 key3这样就可以对key1,key2,key3进行加锁保护,在watch执行之后, exec执行之前, 其他终端客户(或自己)修改了key的值, 那么当前客户端的事务就会失败,返回nil。
unwatch:释放锁,它后面不带key参数,会释放之前所有watch的key,任何时候都返回OK,它能保证下一个事务的执行不会受到影响。.
2)开启事务、中断事务、执行事务
multi:开启一个事务,当客户端发出了multi命令时,客户端和服务端的连接就进入了一个事务上下文的状态。multi执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当exec命令被调用时, 所有队列中的命令才会被执行。在multi之后输入相应的其他操作,例如decrby,incr,set,sadd....这些操作。
discard:放弃事务的执行,用在exec之前,例如发现前面的某个命令输入错误了,可运行该命令放弃事务。这是再执行exec就会报错。
exec:执行事务,当exec运行的时候,在multi之后的QUEUED中的命令会被执行,可以理解成connection.commit()
3)演示
账号里面有100元,买东西,单价20元
4)如何表达一个事务执行的过程?
[watch keys] multi....exec,其中watch是可选的,根据实际需求决定是否要watch.
3.事务的三个场景
1)加锁的变量在未执行exec之前被第三方程序(客户端)更改了值,导致整个事务返回nil
127.0.0.1:6379> WATCH money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> set test test
QUEUED
127.0.0.1:6379> EXEC
(nil)
2)事务中的命令无法通过解释,导致整个事务报错
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> sets remark zheshihaoshangpin
(error) ERR unknown command 'sets'
127.0.0.1:6379> set time 20180307
QUEUED
127.0.0.1:6379> set no 1234234234
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
3)事务中的命令运行时报错误,导致事务部分执行成功
27.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> DECRBY name 20
QUEUED
127.0.0.1:6379> set sex nv
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 40
2) (error) ERR value is not an integer or out of range
3) OK
4.事务总结
1)redis里面的事务是弱事务,即它可以部分执行成功。
2)当执行exec或者discard或者unwatch的时候该命令后watch自动失效,即exec/discard/unwatch命令会取消对所有key的监控。
3)事务中的每个命令的执行结果都是最后一起返回的,所以无法将前一条命令的结果作为下一条命令的参数

1.使用jedis操作redis事务
//如果不写host则默认为localhost
//如果不写端口则默认为6379
Jedis jedis = new Jedis();
jedis.set("money", "100");
//假如需求中需要对money加锁的话则加锁
jedis.watch("money");
//开启事务
Transaction transaction = jedis.multi();
//停止5秒
try {
    Thread.sleep(5000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
//开始往事务队列中添加命令(操作)
transaction.decrBy("money", 20);
transaction.set("name", "zhangsanfeng");
transaction.set("age", "20");
//执行事务
List<Object> exec = transaction.exec();
//打印执行结果
System.out.println(exec);

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值