Redis执行命令的核心模块是单线程的,所以redis中单个命令都是原子的,redis执行单个命令时不会被打断。(而在java中,一个操作执行时cpu可能切换到其他线程导致打断,所以不是原子的)。
Redis事务是一个独立的操作,事务中所有命令都会序列化,按顺序执行。事务执行过程中,不会被其他客户端发送来的命令请求所打断。Redis事务的主要作用就是串联多个命令防止别的命令插队。
- 保证隔离性。不会被其他客户端的请求打断。
- 没有隔离级别。应为事务中的命令在没有执行前都不会实际的被执行,而在执行时又不会被其他所打断,所以不需要隔离级别。
- 不保证原子性。redis同一个事务中如果有一条命令执行失败,其他命令仍然会被执行,没有回滚。但是在执行事务前,具有原子性。
- multi 开启事务,执行该命令会开启事务,此后输入的redis命令并不会立即执行,而是放到等待队列中,直到执行exec或者discard命令。如果放入等待队列中的命令有一条语法错误,则所有命令都不会执行成功。
- exec 执行事务,但是如果事务中的一条命令失败,不影响其他命令的执行。
- discard 解散当前事务。
- watch key [key...]在执行multi之前,先执行watch可以监视一个或多个key,如果再执行之前这些key被其他命令所改动,那么事务将被打断。
- unwatch 取消watch命令对所有key的监视
jedis是redis的java版本的客户端,在java中使用方法比较简单。
- 添加依赖
redis.clients jedis 2.9.0 org.apache.commons commons-pool2
- 编写配置类
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.database}")
private int database;
@Value("${spring.redis.lettuce.pool.max-active}")
private int maxActive;
@Value("${spring.redis.lettuce.pool.max-wait}")
private int maxWait;
@Value("${spring.redis.lettuce.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.lettuce.pool.max-idle}")
private int maxIdle;
@Bean(name= "jedis.pool")
public JedisPool jedisPool(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxWaitMillis(maxWait);
jedisPoolConfig.setMaxTotal(-1);
return new JedisPool(jedisPoolConfig,host,port,timeout,password, database);
}
@Bean(name= "jedis.pool.config")
public JedisPoolConfig jedisPoolConfig () {
JedisPoolConfig config = new JedisPoolConfig();
return config;
}
}
- 获取连接对象
Jedis jedis = jedisPool.getResource();4.Lua脚本
如果说watch是redis提供的乐观锁,那么使用lua脚本就是redis提供的悲观锁。redis会单线程执行lua脚本。
之前所说的事务也是可以一次性执行多条redis命令,而且不会被打断。但是lua可以进行逻辑判断,相当于加了悲观锁,然后执行锁中的方法。



