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(); // 关闭连接
            }
        }
    }
    
    
  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/junlinsky/p/13528468.html
Copyright © 2011-2022 走看看