优势Redis是基于缓存的存储,所以如果服务器宕机,会导致数据丢失,所以如果需要保存在磁盘上,需要使用持久化方案,Redis提供两种的持久化方案,RDB和AOF,默认情况下,开启了RDB方案,关闭AOF方案
也叫做快照模式,只会保存在数据库的最后的结果,并不会保存过程
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set a a
OK
127.0.0.1:6379> set b b
OK
127.0.0.1:6379> set c c
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379>
此命令是阻塞式命令,是同步的。执行数据库的备份,把数据库的数据全部存储到一个dump.rdb文件中。并且服务器在每次启动的时候,都从当前配置文件中,检测rdb和aof文件是否存在,如果存在,则使用rdb和aof文件中的内容,做数据恢复。
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379>
bgsave属于异步非阻塞式命令,后台执行。不阻塞。不影响其他命令的执行。
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储
将内存中的数据以快照的方式写入二进制文件中,默认的文件名是dump.rdb
1、修改redis.conf配置文件
此处表示,如果在60秒内,有100次的修改的话,就会触发RDB
2、需要在运行Redis时,同时加载配置文件,window系统下的做法,创建redis-server.exe
的快捷方式,并在启动路径后追加redis.windows.conf
但是,可能会因此丢失部分数据,在上一次save和这一次save之间的数据,这一次的save还没有发生,此时宕机,则会丢失区间数据。
采用的是一种日志追加的方式来记录Redis相关操作,AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录
修改redis.conf
配置文件,yes
为开启
Redis中事务仅仅保证了隔离性(串行化),保证了一段事务在开启以后,不会被其他的事务所打扰,例如一致性,Redis就无法保证,同一个事务中,出现异常的命令将不会执行,但是其他的正常的命令会执行。
命令 | 描述 |
---|---|
multi | 开始事务用于标记事务块的开始。Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令原子化地执行这个命令序列 |
exec | 执行事务在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。当使用WATCH命令时,只有当受监控的键没有被修改时,EXEC命令才会执行事务中的命令,这种方式利用了检查再设置(CAS)的机制。这个命令的返回值是一个数组,其中的每个元素分别是原子化事务中的每个命令的返回值。 当使用WATCH命令时,如果事务执行中止,那么EXEC命令就会返回一个Null值 |
discard | 回滚清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态。如果使用了WATCH命令,那么DISCARD命令就会将当前连接监控的所有键取消监控 |
watch | 监控指定的key当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的 |
unwatch | 撤销监控 |
watch命令,需要与事务进行配合,在一个用户修改数据之前,如果watch key这个数据,那么如果在这个事务没有提交之前,有其他的用户进行修改此数据的话,那么当前用户的该事务,将被全部丢弃,当前,可以通过逻辑,做到自旋
public class Test4 {
public static void main(String[] args) throws InterruptedException {
Jedis jedis = new Jedis();
System.out.println(jedis.ping());
//查询数据库
while(true) {
Integer count = Integer.parseInt(jedis.get("count"));//查询数据库的库存
//做数据操作之前,必须要watch住,才能保证你做这个数据的时候,没有人进行修改
jedis.watch("count");
Transaction multi = jedis.multi();//事务的开启
multi.set("count", (count - 1) + "");
Thread.sleep(20000);
List<Object> exec = multi.exec();
if(exec != null){
System.out.println("购买成功");
return;
}else{
System.out.println("购买失败,自旋");
}
}
}
}