redis 事务基本用法

基本用法

127.0.0.1:6379> set hz 1000
OK
127.0.0.1:6379> set wangdan 1000
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby hz 100
QUEUED
127.0.0.1:6379> incrby wangdan 100
QUEUED
127.0.0.1:6379> exec
1) (integer) 900
2) (integer) 1100
127.0.0.1:6379> get hz
"900"
127.0.0.1:6379> get wangdan
"1100"
127.0.0.1:6379> 
  • multi 开启事务
  • decrby hz 100                 // hz    减少   100
  • QUERUED                     成功加入队列
  • incrby wangdan 100       //wangdan   增加  100
  • QUERUED                     成功加入队列
  • exec                               关闭事务  返回操作之后的

注意事项

  •     redis事务里面是不可以嵌套事务的。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> multi
(error) ERR MULTI calls can not be nested
127.0.0.1:6379> 
  •     redis事务中如果报错了,事务在什么情况下回滚,什么情况下不会滚,为什么不会回滚。

  1. 运行时的异常(exce之后)不会回滚   编译器没有办法确认的异常是不会全部回滚的
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set h1 1     //对String类型h1的操作
QUEUED
127.0.0.1:6379> hset h1 a b     //因为h1是String类型的key,不能用HASH类型的指令去操作String类型的key
QUEUED
127.0.0.1:6379> exec
1) OK               //第一个入队操作成功
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value   //第二个入队操作报错
127.0.0.1:6379> get h1
"1"               //实际确认  第一个入队操作确实有效
127.0.0.1:6379> hget h1 a
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> 
  1. 编译器能识别(exce命令之前)的情况下(参数名错误,语法的错误,参数数量错误),所有的加入队列的事务操作都会回滚,也就是说在编译时产生的异常都会回滚
127.0.0.1:6379> multi                 
OK
127.0.0.1:6379> set hz 2222
QUEUED
127.0.0.1:6379> hset hc 3333       //hash类型操作  语法有错误
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get hz
(nil)
127.0.0.1:6379> hget hc 333
(nil)
127.0.0.1:6379> 
  1. 至于为什么不回滚,网上大部分人说的都是出现问题应该在开发环境解决,生产环境出现错误的概率非常小,还有就是为了保证redis的速度还是一样的快,还有就是一些编码的问题,incr 1,但是却操作成了 incr 2  对于程序是没有错误的,错误的是在于业务,这些都是属于自己的代码错误。
  2. 参考关于redis为什么不支持回滚操作. - 割肉机 - 博客园
  •     如果在事务执行中,想放弃这次事务的执行,怎么做? 可以使用discard命令 取消事务

127.0.0.1:6379> keys *
1) "hz"
2) "wangdan"
3) "qingshan"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a1  1
QUEUED
127.0.0.1:6379> set a2  2
QUEUED
127.0.0.1:6379> set a3 3
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> keys *
1) "hz"
2) "wangdan"
3) "qingshan"
127.0.0.1:6379> 
  • watch  乐观锁  (监视一个或者多个key,如果被监视的key中途被修改了,整个事务都会被取消)

127.0.0.1:6379> set balance 100
OK
127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby balance 200
QUEUED
127.0.0.1:6379> incrby balance 200
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get balance 
"1100"
127.0.0.1:6379> 


线程A
127.0.0.1:6379> incrby balance 1000     //在执行事务中,执行
(integer) 1100
127.0.0.1:6379> 
线程B

 
// 类似于抢票(可能不准确) 与乐观锁的意思差不多
// 初始化只有一张票  线程A选车选坐,准备付钱。
// 同时线程B是黄牛,各种抢票软件,直接付钱成功,这时唯一的票实际已经没有了
// 所以这时A即使付钱了,票也没了,返回购票失败,所有的选车选座操作全部回滚,等有票了再来一遍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis事务可以让多个命令一起执行,保证在执行过程中不会有其他客户端访问和修改相同的数据,保证了数据的一致性和完整性。在Java中,可以通过Jedis的事务对象实现Redis事务。 首先,需要创建一个Jedis对象,并连接到Redis服务器: ```java Jedis jedis = new Jedis("localhost", 6379); jedis.connect(); ``` 然后,可以创建一个事务对象: ```java Transaction transaction = jedis.multi(); ``` 通过multi()方法创建的事务对象可以执行多个命令,这些命令会一起提交到Redis服务器,但是并不会立即执行,而是在调用exec()方法时执行。 例如,可以在事务中执行一个字符串的设置操作和一个列表的插入操作: ```java transaction.set("key1", "value1"); transaction.lpush("list1", "item1", "item2", "item3"); ``` 然后,可以调用exec()方法提交事务并执行命令: ```java List<Object> results = transaction.exec(); ``` exec()方法会返回一个包含所有命令执行结果的列表,每个命令的执行结果都是一个对象。如果在事务中有任何一个命令执行失败,exec()方法会返回null,表示整个事务执行失败。 完整的代码示例: ```java Jedis jedis = new Jedis("localhost", 6379); jedis.connect(); Transaction transaction = jedis.multi(); transaction.set("key1", "value1"); transaction.lpush("list1", "item1", "item2", "item3"); List<Object> results = transaction.exec(); jedis.disconnect(); ``` 需要注意的是,Redis事务并不是原子性的,如果在事务执行期间有其他客户端修改了相同的数据,那么事务的执行结果可能会与预期不一致。因此,在使用Redis事务时需要谨慎处理数据的一致性和并发访问的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值