一、事务
Redis的单条命令是保证原子性的,要么同时成功,要么同时失败。
但是事务不保证原子性
Redis事务本质:一组命令的集合,一个事务中所有命令都会被序列化,在事务执行过程中,会按照顺序执行、一次性,排他性(不允许被打扰)
--------队列 set set set 执行-------
Redis事务没有隔离级别的概念
所有的命令在事务中,并没有被直接执行。只有发起执行命令的时候才会执行!Exec
Redis的事物包括以下三个过程
-
开启事务(multi)
-
命令入队(写命令)
-
执行事务(exec)
Redis可以实现乐观锁
正常执行事务操作如下:
开启事务:multi
执行事务:exec
exec后出现事务的结果
还可以放弃事务
DISCARD:放弃事务,事务中的命令都不会被执行
编译型异常(Redis命令有错),事务中的所有命令都不会被执行
此时所有的命令都不会被执行。
运行时异常(比如1/0),事务中的其他命令正常执行,错误的命令会抛出异常
解释:incr k1 是错误的命令,运行时会报异常,但是不影响整个事务的命令
二、监控
悲观锁:无论做什么都会加锁
乐观锁:认为什么时候都不会出问题,所以都不会上锁,更新数据的时候去判断一下,在此期间是否有人修改过这个数据;
获取version;
更新的时候比较version
Redis测监视测试(正常执行成功,监视money对象)
测试多线程修改值,使用watch可以当做redis的乐观锁操作,
注意:
watch指令在一次事务执行完毕后,即结束其生命周期
![](https://i-blog.csdnimg.cn/blog_migrate/714d7fe707ab1d03aeb01b02cc782876.png)
解释:watch money :监视money
exec :执行之前,右边的一个新的线程修改了我们的值,这个时候就会导致事务失败
watch值发生变化则执行失败,执行失败还有办法挽救吗?
解决方法:
UNWATCH :解锁
如果执行失败,则先解锁,再重新监控最新版本
三、Jedis(以下所有操作开始前请打开你的redis-server.exe)
Jedis是Redis官方推荐的java连接开发工具
如何用Jedis连接Redis
1.新建项目project,选择Maven
![](https://i-blog.csdnimg.cn/blog_migrate/f3f50091eb042c509b943f24f5aff530.png)
找到Maven下的pom.xml
![](https://i-blog.csdnimg.cn/blog_migrate/aa24d02d36e87b74981d30895a8ea3c9.png)
2.
导入maven依赖,这里给出下载依赖包的地址
![](https://i-blog.csdnimg.cn/blog_migrate/8740f12368989477433a9596e59caf29.png)
将最下面方框的<dependency></dependency>代码复制到
pom.xml中,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/866e10ff398b2ad2f119c5feb6a02deb.png)
需要建立“jedis”和“fastjson”依赖,注意上下两个<dependencies>
</dependencies>
这里出现错误(注意建立新项目的时候版本要统一)
![](https://i-blog.csdnimg.cn/blog_migrate/2d40035d3e2d8e8fe17a9f70e9a0a3c4.png)
查询原因,
本地运行用的是JDK11,测试Java的Stream操作
报错应该是项目编译配置使用的Java版本不对,需要检查一下项目及环境使用的Java编译版本配置。
找到IDEA右上角的按钮,设置“project”和“Modules”的版本,我这里是11,你们设置成你们默认的就好
![](https://i-blog.csdnimg.cn/blog_migrate/60562e12f322889458cc50fe07a5fb88.png)
![](https://i-blog.csdnimg.cn/blog_migrate/77a75b32358a338055fcaf351e4faeda.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fea58d717f216b8569c9fa838000a181.png)
打开Settings”-->“Bulid, Execution,Deployment”-->“Java Compiler”,Target bytecode version设为本地Java版本。
![](https://i-blog.csdnimg.cn/blog_migrate/f68332dfd799b254f82aa05bcadd7c3b.png)
测试连接(新建class)
package com.kuang;
import java.util.Set;
import redis.clients.jedis.Jedis;
public class TestPing {
public static void main(String[] args){
// new 一个Jedis对象
Jedis jedis = new Jedis("127.0.0.1",6379);
// Jedis所有的命令就是之前学习的所有指令(变成了方法)
System.out.println(jedis.ping());
}
}
连接成功
![](https://i-blog.csdnimg.cn/blog_migrate/b5f7075fe289360173fbba0a501e0600.png)
测试:
package com.kuang;
import java.util.Set;
import redis.clients.jedis.Jedis;
public class TestPing {
public static void main(String[] args){
// new 一个Jedis对象
Jedis jedis = new Jedis("127.0.0.1",6379);
// Jedis所有的命令就是之前学习的所有指令(变成了方法)
System.out.println(jedis.ping());
System.out.println("清空数据库:"+jedis.flushDB());
System.out.println("判断某个键是否存在:"+jedis.exists("k1"));
System.out.println("新增键值对"+jedis.set("k1","v1"));
System.out.println("新增k2,v2键值对:"+jedis.get("k1"));
System.out.println("系统中所有的键如下:");
Set Stringkeys = jedis.keys("*");
System.out.println(Stringkeys);
System.out.println("删除键k2:"+jedis.del("k2"));
System.out.println("判断键k2是否存在:"+jedis.exists("k2"));
System.out.println("查看键 k1 所存储的数据类型:"+jedis.type("k1"));
System.out.println("随机返回 key 空间的一个:"+jedis.randomKey());
System.out.println("重命名 key :"+jedis.rename("k1","newk1"));
System.out.println("取出改后的 newk1 :"+jedis.get("newk1"));
System.out.println("按索引查询:"+jedis.select(0));
System.out.println("删除当前选择数据库中的所有键:"+jedis.flushDB());
System.out.println("返回当前数据库中 key 的数量:"+jedis.dbSize());
System.out.println("删除所有数据库中的所有 key :"+jedis.flushAll());
}
}
结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/80effc70b837fe4948c67f15d603347e.png)
四、通过Jedis理解事务
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("127.0.0.1",6379);
System.out.println(jedis.ping());
JSONObject jsonObject = new JSONObject();
jsonObject.put("hello","world");
jsonObject.put("name","vv");
// 开启事务
Transaction multi = jedis.multi();
String result = jsonObject.toJSONString();
try{
multi.set("user1",result);
multi.set("user2",result);
multi.exec(); // 执行事务
//int i = 1/0;
}catch (Exception e){
multi.discard(); // 放弃事务
e.printStackTrace();
}finally{
System.out.println(jedis.get("user1"));
System.out.println(jedis.get("user2"));
jedis.close();// 关闭连接
}
}
}
结果如下:添加成功
有的会出现错误:
这个时候在pom里面加入依赖
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.2</version>
</dependency>
OK