zoukankan      html  css  js  c++  java
  • redis事务和Jedis

    事务

    Redis 事务本质:一组命令的集合! 一个事务中的所有命令都会被序列化,在事务执行过程的中,会按 照顺序执行!

    一次性、顺序性、排他性!执行一些列的命令!

    ------ 队列 set set set 执行------
    

    Redis事务没有没有隔离级别的概念!

    所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行!Exec

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

    redis的事务:

    • 开启事务(multi)
    • 命令入队(......)
    • 执行事务(exec)

    正常执行事务!

    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> get k2
    QUEUED
    127.0.0.1:6379> set k3 v3
    QUEUED
    127.0.0.1:6379> exec # 执行事务
    1) OK
    2) OK
    3) "v2"
    4) OK
    

    放弃事务!

    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> set k4 v4
    QUEUED
    127.0.0.1:6379> DISCARD # 取消事务
    OK
    127.0.0.1:6379> get k4 # 事务队列中命令都不会被执行!
    (nil)
    

    编译型异常(代码有问题! 命令有错!),事务中所有的命令都不会被执行!

    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> set k3 v3
    QUEUED
    127.0.0.1:6379> getset k3 # 错误的命令
    (error) ERR wrong number of arguments for 'getset' command
    127.0.0.1:6379> set k4 v4
    QUEUED
    127.0.0.1:6379> set k5 v5
    QUEUED
    127.0.0.1:6379> exec # 执行事务报错!
    (error) EXECABORT Transaction discarded because of previous errors.
    127.0.0.1:6379> get k5 # 所有的命令都不会被执行!
    (nil)
    
    

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

    127.0.0.1:6379> set k1 "v1"
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> incr k1 # 会执行的时候失败!
    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) (error) ERR value is not an integer or out of range # 虽然第一条命令报错了,但是依旧正常执行成功了!
    2) OK
    3) OK
    4) "v3"
    127.0.0.1:6379> get k2
    "v2"
    127.0.0.1:6379> get k3
    "v3"
    

    监控! Watch (面试常问!)

    悲观锁:

    • 很悲观,认为什么时候都会出问题,无论做什么都会加锁!

    乐观锁:

    • 很乐观,认为什么时候都不会出问题,所以不会上锁! 更新数据的时候去判断一下,在此期间是否 有人修改过这个数据,
    • 获取version
    • 更新的时候比较 version

    Redis监视测试

    正常执行成功!

    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 # 监视 money 对象
    OK
    127.0.0.1:6379> multi # 事务正常结束,数据期间没有发生变动,这个时候就正常执行成功!
    OK
    127.0.0.1:6379> DECRBY money 20
    QUEUED
    127.0.0.1:6379> INCRBY out 20
    QUEUED
    127.0.0.1:6379> exec
    1) (integer) 80
    2) (integer) 20
    

    测试多线程修改值 , 使用watch 可以当做redis的乐观锁操作!

    127.0.0.1:6379> watch money # 监视 money
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> DECRBY money 10
    QUEUED
    127.0.0.1:6379> INCRBY out 10
    QUEUED
    127.0.0.1:6379> exec # 执行之前,另外一个线程,修改了我们的值,这个时候,就会导致事务执行失败!
    (nil)
    

    如果修改失败,获取最新的值就好

    image-20200519213609873

    Jedis

    什么是Jedis

    • Jedis 是 Redis 官方推荐的 java连接开发工具! 使用Java 操作Redis 中间件!如果你要使用 java操作redis,那么一定要对Jedis 十分的熟悉!

    测试

    1. 导入对应的依赖
    <!--导入jedis的包-->
    <dependencies>
    	<!--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.62</version>
        </dependency>
    </dependencies>
    
    1. 编码测试:

      • 连接数据库
      • 操作命令
      • 断开连接!
      package com.maple;
      import redis.clients.jedis.Jedis;
      public class TestPing {
          public static void main(String[] args){
              // 1、 new Jedis 对象即可
              Jedis jedis = new Jedis("127.0.0.1",6379);
              // jedis 所有的命令就是我们之前学习的所有指令!
              System.out.println(jedis.ping());
          }
      }
      

      输出:

      PONG
      name:枫叶age:18

    常用的API

    • String

    • List

    • Set

    • Hash

    • Zset

    所有的api命令,就是我们对应的上面学习的指令,一个都没有变化!

    事务

    public class TestTX {
        public static void main(String[] args) {
            Jedis jedis = new Jedis("127.0.0.1", 6379);
            jedis.flushDB();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("hello","world");
            jsonObject.put("name","kuangshen");
            // 开启事务
            Transaction multi = jedis.multi();
            String result = jsonObject.toJSONString();
                // jedis.watch(result)
            try {
                multi.set("user1",result);
                multi.set("user2",result);
                int i = 1/0 ; // 代码抛出异常事务,执行失败!
                multi.exec(); // 执行事务!
            } catch (Exception e) {
                multi.discard(); // 放弃事务
                e.printStackTrace();
            } finally {
                System.out.println(jedis.get("user1"));
                System.out.println(jedis.get("user2"));
                jedis.close(); // 关闭连接
            }
        }
    }
    
    
  • 相关阅读:
    关于Idea中右边的maven projects窗口找不到了如何调出来
    如何解决IntelliJ idea的maven工程提示的Cannot Resolve Symbol
    代码战争
    golang学习笔记----并发
    golang --学习笔记 运行时间计算
    golang ---timeb
    go ---MQTT client
    golang --strings
    Windows ----tasklist/taskkill
    转Tasklist(windows)
  • 原文地址:https://www.cnblogs.com/junlinsky/p/13528468.html
Copyright © 2011-2022 走看看