Redis事务与基本实现代码

redis事务的本质是:一组命令的集合,一个事务中所有命令都会被按顺序放在队列中,在发起执行命令的时候队列中的命令会被一一执行

  • Redis事务没有隔离级别的概念
  • Redis单条命令保证原子性,但是事务不保证原子性
    redis事务:
  1. 开启事务(multi)
  2. 命令入队(……)
  3. 执行事务(exec)

正常执行事务

127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
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) OK
3) OK
4) "v3"

放弃事务的执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get k2
(nil)

命令错误 所有的命令都不会被执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> sett k1 v2
(error) ERR unknown command `sett`, with args beginning with: `k1`, `v2`,
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

运行时异常,队列中的命令存在语法性的错误,执行的时候其他命令是可以执行的,错误命令抛出异常

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 "v1"
QUEUED
127.0.0.1:6379> incr k1  		#有语法错误,其作用是为k1上的值加1,如果k1的值不是数字就会报错
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
4) "v2"

监控命令
watch(乐观锁机制)

127.0.0.1:6379> watch money		#监控money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10  #让money减10
QUEUED
127.0.0.1:6379> exec		#在执行前开启另外一个客户端修改money的值,就会执行失败
(nil)
127.0.0.1:6379> get money
(nil)
127.0.0.1:6379> set money 100
OK

如果修改失败,我们将其解锁再重新监控就好

127.0.0.1:6379> Unwatch		#解锁
OK
127.0.0.1:6379> watch money	#重新监控money
OK
127.0.0.1:6379> multi		
OK
127.0.0.1:6379> decrby money 10	#让money减10
QUEUED
127.0.0.1:6379> exec			#执行
1) (integer) 90

代码中使用Redis

Jedis是Redis官方推荐的Java连接Redis工具
导入包:

<dependencies> 
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.2.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>
</dependencies>

Jedis所有函数都与Redis中的命令行相同

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

/**
 * redis测试
 * 测试redis的事务
 */
public class RedisDemo {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("127.0.0.1",6379);

        jedis.flushDB();

        Transaction multi = jedis.multi();
        try {
            multi.set("user1", "张三");
            multi.set("user2", "李四");
            int i = 1/0;// 报错放弃事务
            multi.exec();
        } catch (Exception e){
            multi.discard();// 放弃事务
            e.printStackTrace();
        }finally {
            jedis.close();
        }
        System.out.println(jedis.get("user1"));
    }
}

输出:

java.lang.ArithmeticException: / by zero
	at RedisDemo.main(RedisDemo.java:17)
null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值