Redis事务

梦想不抛弃苦心追求的人,只要不停止追求,你们会沐浴在梦想的光辉之中。再美好的梦想与目标,再完美的计划和方案,如果不能尽快在行动中落实,最终只能是纸上谈兵,空想一番。只要瞄准了大方向,坚持不懈地做下去,才能够扫除挡在梦想前面的障碍,实现美好的人生蓝图。Redis事务,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

Redis单条命令是原子性的,但是事务不保证原子性

Redis事务没有隔离级别的概念,所有的命令在事务中没有被直接执行,只有发起执行命令的时候才会执行 Exec

Redis事务本质:一组命令的集合,一个事务中的所有的命令都会被序列化,在事务执行过程中,会按照顺序执行。
在这里插入图片描述

三个特性

一次性、顺序性、排他性

Redis事务

  1. 开启事务(multi)
  2. 命令入队(…)
  3. 执行事务(exec)
    在这里插入图片描述
    执行完一组就要重新开启

放弃事务
在这里插入图片描述

编译型异常(代码有问题!命令有错! ),事务中所有的命令都不会被执行!
在这里插入图片描述

运行时异常(1/0),如果事务队列中存在语法性错误,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常!
在这里插入图片描述

原子性定义:1.要么全部执行成功,要么异常全不执行;2.异常发生后,可以回滚,就像没执行过一样;Redis事务异常以后其他命令依旧执行,没有发生回滚,Redis大部分是命令语法错误引发异常。

监控(Watch)

悲观锁:
很悲观,无论执行什么操作都会出现问题,所以会对所有的操作加锁
乐观锁
很乐观,任何情况下都不会出问题,所以不会加锁!但是在数据更新时需要判断在此之前是否有人修改过这个数据
可以添加一个字段叫version用来查询(标记号)
在进行数据更新时对version进行比较
测试多线程修改值,使用watch可以当做redis的乐观锁操作!

Redis监视测试
在这里插入图片描述

127.0.0.1:6379> WATCH money
OK
127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> DECRBY money 30
QUEUED
127.0.0.1:6379> INCRBY out 30
QUEUED
# 这个时候开始模拟另外一个客户端恶意修改被监控的key
# =======================================================表示另一个客户端==============================================================
127.0.0.1:6379> get money
"80"
127.0.0.1:6379> INCRBY money 200 # 修改被监控的数据
(integer) 280
127.0.0.1:6379> get money
"280"
# ===================================================================================================================================
# 再次执行事务,会直接返回nil,代表执行失败
127.0.0.1:6379> EXEC 
(nil)
127.0.0.1:6379> get money # 再次查看,当前监控的key已经被修改
"280"
# 多聊一嘴:实际上关于WATCH,还有一个命令,UNWATCH,意思是解除所有监控,但是官网的原话是,一旦你执行了DISCARD或者EXEC,就没必要在执行UNWATCH
127.0.0.1:6379> MGET money out
1) "280"
2) "20"
127.0.0.1:6379> WATCH money 
OK
127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> DECRBY money 30 
QUEUED
127.0.0.1:6379> INCRBY out 30
QUEUED
127.0.0.1:6379> EXEC 
1) (integer) 250
2) (integer) 50

如果修改失败获取最新的值
在这里插入图片描述

Jedis

什么是Jedis
Jedis是Redis官方推荐的Java连接Redis的连接开发工具!使用Java操作Redis的中间件

<!--导入Jedis-->
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>3.2.0</version>
</dependency>
<!--fastjson-->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.70</version>
</dependency>

编码测试

  1. 连接数据库
  2. 操作命令
  3. 断开连接

先在服务器中开放安全组6379端口,之后
2.xshell连接服务器。然后输入ifconfig

得到以下的图片
在这里插入图片描述
这两个ip请记住,尤其第一个,第二个是默认的。
3.使用vim打开redis.conf (文件目录自己清楚)
然后找到bind 配置第二步找到的ip地址。

如图
在这里插入图片描述
运行:wq!保存
之后重启redis
在这里插入图片描述


import redis.clients.jedis.Jedis;

public class TestPing {
    public static void main(String[] args) {
        // new一个Jedis对象
        Jedis jedis = new Jedis("121.4.127.10", 6379);
        // Jedis中的API就是之前学习的命令
        System.out.println(jedis.ping());
        System.out.println("清空数据"+jedis.flushDB());

        // String
        System.out.println(jedis.set("k1", "v1"));
        System.out.println(jedis.get("k1")); // v1
        System.out.println(jedis.append("k1", "+value"));
        System.out.println(jedis.get("k1")); // v1+value
        System.out.println(jedis.strlen("k1")); // 8
        System.out.println("=====================================================");
        // List
        System.out.println(jedis.lpush("listKey", "l1", "l2", "l3"));
        System.out.println(jedis.lrange("listKey", 0, -1)); // [l3, l2, l1]
        System.out.println(jedis.llen("listKey"));
        System.out.println("=====================================================");
        // Hash
        System.out.println(jedis.hset("hashKey", "k1", "v1"));
        System.out.println(jedis.hset("hashKey", "k2", "v2"));
        System.out.println(jedis.hset("hashKey", "k3", "v3"));
        System.out.println(jedis.hmget("hashKey", "k1", "k2", "k3")); // [v1, v2, v3]
        System.out.println(jedis.hgetAll("hashKey")); // {k3=v3, k2=v2, k1=v1}
        System.out.println("=====================================================");
        // Set
        System.out.println(jedis.sadd("setKey", "s1", "s2", "s3", "s4"));
        System.out.println(jedis.smembers("setKey")); // [s2, s1, s4, s3]
        System.out.println(jedis.scard("setKey"));
        System.out.println("=====================================================");
        // ZSet
        System.out.println(jedis.zadd("ZKey", 90, "z1"));
        System.out.println(jedis.zadd("ZKey", 80, "z2"));
        System.out.println(jedis.zadd("ZKey", 85, "z3"));
        System.out.println(jedis.zrange("ZKey", 0, -1)); // [z2, z3, z1]
    }
}
PONG
清空数据OK
OK
v1
8
v1+value
8
=====================================================
3
[l3, l2, l1]
3
=====================================================
1
1
1
[v1, v2, v3]
{k3=v3, k1=v1, k2=v2}
=====================================================
4
[s4, s1, s3, s2]
4
=====================================================
1
1
1
[z2, z3, z1]

Process finished with exit code 0

事务

import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class TestTx {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.1.107", 6379);
        jedis.flushDB();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", "xiaohuang");
        jsonObject.put("age", "21");
        jsonObject.put("sex", "boy");
        Transaction multi = jedis.multi(); //  开启事务
        String user = jsonObject.toJSONString();
        try {
            multi.set("user1", user);
            multi.set("user2", user);
            multi.exec();
        } catch (Exception e) {
            multi.discard(); // 出现问题,放弃事务
            e.printStackTrace();
        } finally {
            System.out.println(jedis.mget("user1", "user2"));
            jedis.close(); // 关闭连接
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/152862.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!