本质
redis事务本质: 一组命令的集合! 一个事务中的所有命令都会被序列化, 在事务执行的过程中会按照顺序执行!
特性
事务特性: 一次性, 顺序性,排他性
Redis单条命令是保证原子性的, 但是redis的事务不保证原子性
redis事务没有隔离级别的概念!
所有命令在事务中,并没有直接被执行,只有发起执行命令的时候才会执行 ! Exec
------队列 set set set 执行----
redis 事务流程
- 开启事务(multi)
- 命令入队 .....
- 执行事务(exec)
正常执行事务
127.0.0.1:6379> multi //开启事务
OK
127.0.0.1:6379(TX)> set k1 v1 //入队
QUEUED
127.0.0.1:6379(TX)> set k2 v2 //入队
QUEUED
127.0.0.1:6379(TX)> set k3 v3 //入队
QUEUED
127.0.0.1:6379(TX)> get k2 //入队
QUEUED
127.0.0.1:6379(TX)> exec //执行
1) OK
2) OK
3) OK
4) "v2"
放弃事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> discard
OK
127.0.0.1:6379> get k4
(nil)
编译型异常
编译型异常(代码有问题,命令有错) 事务中所有的命令都不会被执行!
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> getset k3
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k2
(nil)
运行时异常
运行时异常(1/0),如果事务队列中存在语法性错误,那么执行命令的时候其他命令是可以正常执行的,错误命令抛出异常
127.0.0.1:6379> set k1 "v1"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incr k1 //字符串无法自增, 可以入队,但是执行会报错
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> get k3
QUEUED
127.0.0.1:6379(TX)> 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 k3
"v3"
127.0.0.1:6379> get k2
"v2"
在java中使用jedis
导入坐标
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.4.1</version>
</dependency>
public class TXtest {
public static void main(String[] args) {
Jedis jedis=new Jedis("127.0.0.1",6379);
jedis.select(1);
jedis.flushDB();
String s="HELLO ,WORLD";
Transaction multi = jedis.multi();
multi.multi();
try{
multi.set("v1",s);
multi.set("v2",s);
multi.set("v3",s);
int a=1/0;
multi.exec();
}catch (Exception e){
multi.discard();
e.printStackTrace();
}finally {
System.out.println("=============");
jedis.close();
}
System.out.println(jedis.get("v1"));
}
}
输出结果
java.lang.ArithmeticException: / by zero at com.hc.TXtest.main(TXtest.java:18)
=============
null