Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
批量操作在发送 EXEC 命令前被放入队列缓存。
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
开始事务。
命令入队。
执行事务
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
DISCARD:取消事务,放弃执行事务块内的所有命令。
EXEC:执行所有事务块内的命令。
MULTI:标记一个事务块的开始。
UNWATCH:取消 WATCH 命令对所有 key 的监视。
WATCH key [key ...]:监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
import com.redis.utils.RedisConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;
import java.util.Map;
/**
* @author Administrator
* @description 事务
* @date 2020/1/7
*/
public class RedisTransaction {
private static Jedis jedis = RedisConfig.getJedis();
public static void main(String[] args) {
// test();
// test1();
// test2();
// test3();
test4();
}
/**
* 功能描述: 正常执行事务
* @Param: []
* @Return: void
* @Author: Administrator
* @Date: 2020/1/7 9:11
*/
public static void test(){
Transaction tr = jedis.multi();
tr.lpush("user","zhangsan");
tr.lpush("user","lisi");
tr.lpush("user","wangwu");
List<Object> exec = tr.exec();
System.out.println("--->"+exec);
// System.out.println(jedis.lrange("user",0,jedis.llen("user")));
while (jedis.llen("user")>0){
System.out.print("--"+jedis.lpop("user")+"--");
}
}
/**
* 功能描述: 事务过程中抛出异常,事务中断,命令都不生效
* @Param: []
* @Return: void
* @Author: Administrator
* @Date: 2020/1/7 9:18
*/
public static void test1(){
try {
Transaction tr = jedis.multi();
tr.lpush("user","zhangsan");
tr.lpush("user","lisi");
int a = 6/0;
tr.lindex("user",5);
tr.lpush("user","wangwu");
List<Object> exec = tr.exec();
System.out.println("\n"+"--->"+exec);
while (jedis.llen("user")>0){
System.out.print("--"+jedis.lpop("user")+"--");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 功能描述: DISCARD:取消事务,放弃执行事务块内的所有命令。所有操作不生效
* @Param: []
* @Return: void
* @Author: Administrator
* @Date: 2020/1/7 10:14
*/
public static void test2(){
String watch = jedis.watch("user");
Transaction tr = jedis.multi();
tr.lpush("user","zhangsan");
tr.lpush("user","lisi");
tr.lpush("user","wangwu");
//取消事务,前面的操作不会生效
String discard = tr.discard();
while (jedis.llen("user")>0){
System.out.print("--"+jedis.lpop("user")+"--");
}
}
/**
* 功能描述:出现语法错误时,不影响其他命令执行
* @Param: []
* @Return: void
* @Author: Administrator
* @Date: 2020/1/7 10:35
*/
public static void test3(){
Transaction tr = jedis.multi();
tr.set("phone","iphone");
tr.set("book","book");
tr.incr("book");
tr.set("tree","tree");
List<Object> exec = tr.exec();
System.out.println(jedis.get("phone")+"--"+jedis.get("book")+"--"+jedis.get("tree"));
jedis.del("phone");
jedis.del("book");
jedis.del("tree");
}
}