6、Redis Lettuce实战(含Spring Boot)

在【Redis Jedis实战(含Spring Boot)】基础上做如下修改:
1、子pom.xml
去掉


	redis.clients
	jedis

  		
	    	io.lettuce
           	lettuce-core
   		
   	

springboot2的spring-boot-starter-data-redis默认就引入lettuce。

2、Lettuce+SpringBoot实战
【--------------------------------单机--------------------------------】

application.yml

spring: 
  redis: 
    host: 192.168.78.169
    port: 6379
    # password: 123456
    database: 0
    timeout: 60000
    lettuce: 
      pool: 
        maxActive: 20
        maxIdle: 20
        minIdle: 0
        maxWait: 60000

【--------------------------------sentinel哨兵模式--------------------------------】
application.yml

spring: 
  redis: 
    database: 0
    timeout: 60000
    # password: 123456
    lettuce: 
      pool: 
        maxActive: 15
        maxIdle: 15
        minIdle: 0
        maxWait: 60000
    sentinel: 
      master: mymaster
      nodes: 192.168.78.169:26379,192.168.78.169:26380,192.168.78.169:26381

【--------------------------------cluster集群模式--------------------------------】
application.yml

spring: 
  redis: 
    database: 0
    timeout: 60000
    # password: 123456
    lettuce: 
      pool: 
        maxActive: 15
        maxIdle: 15
        minIdle: 0
        maxWait: 60000
    cluster: 
      nodes: 
        - 192.168.78.169:6379
        - 192.168.78.169:6380
        - 192.168.78.169:6381
        - 192.168.78.169:6382
        - 192.168.78.169:6383
        - 192.168.78.169:6384

总结:
1、可以使用springboot默认的RedisConnectionFactory为LettuceConnectionFactory,debug方式查看connectionFactory的默认实现类(其他雷同);
2、自定义@Bean(LettuceConnectionFactory),其中构造函数的参数也可以使用自定义bean覆盖springboot默认提供的bean;
例如:

package com.java.ashare.redis.config;

import java.time.Duration;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
	@Value("${spring.redis.sentinel.master}")
	private String master;
	@Value("${spring.redis.sentinel.nodes}")
	private String nodes;
    
	@Value("${spring.redis.database}")
    private int database;
	
	@Value("${spring.redis.timeout}")
    private long timeout;
	
    //@Value("${spring.redis.password}")
    //private String password;
	   
    @Bean
    @ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
    public GenericObjectPoolConfig GenericObjectPoolConfig() {
    	
    	GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
    	return genericObjectPoolConfig;
    }
    
    @Bean
    public LettuceClientConfiguration lettuceClientConfiguration(GenericObjectPoolConfig genericObjectPoolConfig){
    	
        LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder()
        		.poolConfig(genericObjectPoolConfig)
        		.commandTimeout(Duration.ofMillis(timeout))
        		.build();
        return lettucePoolingClientConfiguration;
    }
    
    @Bean
    public RedisSentinelConfiguration redisSentinelConfiguration() {
    	
    	RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
    	redisSentinelConfiguration.setMaster(master);
        // redisSentinelConfiguration.setPassword(RedisPassword.of(password.toCharArray()));
    	redisSentinelConfiguration.setDatabase(database);
		
		String[] addrArr = nodes.split(",");
		for(String addr : addrArr) {
			String[] item = addr.split(":");
			String ip = item[0];
			String port = item[1];
			redisSentinelConfiguration.addSentinel(new RedisNode(ip, Integer.parseInt(port)));
		}
		
    	return redisSentinelConfiguration;
    }
    
	@Bean
    public LettuceConnectionFactory lettuceConnectionFactory(RedisSentinelConfiguration redisSentinelConfiguration, 
    		LettuceClientConfiguration lettuceClientConfiguration) {
        
		LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisSentinelConfiguration, lettuceClientConfiguration);
		return lettuceConnectionFactory;
    }
	
	@Bean
	public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
	
		RedisTemplate redisTemplate = new RedisTemplate();
		
        // key使用字符串序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        
        // value使用fastjson序列化,fastjson比jackson速度快
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer();
        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
        
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
	}
}

3、Lettuce单独实战
Lettuce入门

package com.java.ashare.redis.clients.lettuce;

import java.time.Duration;

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.sync.RedisCommands;

public class LettuceRumen {

	public static void main(String[] args) {
		
		RedisURI redisURI = null;
		RedisClient redisClient = null;
		StatefulRedisConnection connection = null;
		RedisCommands redisCommands = null;
		RedisAsyncCommands redisAsyncCommands = null;
		RedisReactiveCommands redisReactiveCommands = null;
		
		try {
			// redis连接信息---单机
			redisURI = RedisURI.builder()
					.withHost("192.168.78.169")
					.withPort(6379)
					//.withPassword("123456")
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			// redis客户端
			redisClient = RedisClient.create(redisURI);
			// redis连接
			connection = redisClient.connect();
			
			// redis命令API接口
			// sync:同步阻塞等待服务器返回结果	*******************************************************************************
			/*
			redisCommands = connection.sync();
			
			// 测试服务是否正常
			String pong = redisCommands.ping();
			if("PONG".equals(pong)) {
				System.out.println("redis服务正常......");
			}
			
			// 基本操作
			redisCommands.del("key", "key1");
			redisCommands.expire("key", 60);
			redisCommands.expireat("key", new Date());
			redisCommands.pexpire("key", 60000);
			redisCommands.persist("key");
			redisCommands.exists("key", "key1");
			redisCommands.dbsize();
			redisCommands.flushdb();
			redisCommands.flushdbAsync();
			redisCommands.flushall();
			redisCommands.flushallAsync();
			redisCommands.select(0);
			redisCommands.keys("pattern");
			redisCommands.scan();
			
			// 字符串操作
			redisCommands.set("key", "value");
			redisCommands.mset(new HashMap());
			redisCommands.setnx("key", "value");
			redisCommands.setex("key", 60, "value");
			
			SetArgs setArgs = SetArgs.Builder.nx().ex(60);
			redisCommands.set("key", "value", setArgs);
			
			redisCommands.get("key");
			redisCommands.mget("key", "key1");
			redisCommands.incr("key");
			redisCommands.incrby("key", 10);
			redisCommands.decr("key");
			redisCommands.decrby("key", 10);
			
			// 哈希操作
			redisCommands.hset("key", "field", "value");
			redisCommands.hsetnx("key", "field", "value");
			redisCommands.hmset("key", new HashMap());
			redisCommands.hget("key", "field");
			redisCommands.hmget("key", "field", "field1");
			redisCommands.hgetall("key");
			redisCommands.hexists("key", "field");
			redisCommands.hdel("key", "field", "field1");
			redisCommands.hlen("key");
			redisCommands.hincrby("key", "field", 1);
			redisCommands.hincrbyfloat("key", "field", 1.1);
			
			// 列表操作
			redisCommands.lpush("key", "value", "value1");
			redisCommands.rpush("key", "value", "value1");
			redisCommands.lpop("key");
			redisCommands.rpop("key");
			redisCommands.blpop(60, "key", "key1");
			redisCommands.brpop(60, "key", "key1");
			redisCommands.lrange("key", 0, 10);
			redisCommands.llen("key");
			
			// 集合操作
			redisCommands.sadd("key", "member", "member1");
			redisCommands.srem("key", "member", "member1");
			redisCommands.smembers("key");
			redisCommands.scard("key");
			redisCommands.sismember("key", "member");
			redisCommands.srandmember("key");
			redisCommands.srandmember("key", 10);
			redisCommands.spop("key");
			redisCommands.spop("key", 10);
			redisCommands.sinter("key", "key1");
			redisCommands.sinterstore("destination", "key", "key1");
			redisCommands.sunion("key", "key1");
			redisCommands.sunionstore("destination", "key", "key1");
			redisCommands.sdiff("key", "key1");
			redisCommands.sdiffstore("destination", "key", "key1");
			
			// 有序集合操作
			redisCommands.zadd("key", 80, "member");
			redisCommands.zadd("key", 80, "member", 70, "member1");
			redisCommands.zcard("key");
			
			Range range = Range.create(0, 100);
			redisCommands.zcount("key", range);
			
			redisCommands.zrank("key", "member");
			redisCommands.zrevrank("key", "member");
			redisCommands.zrange("key", 0, 10);
			redisCommands.zrevrange("key", 0, 10);
			redisCommands.zscore("key", "member");
			redisCommands.zinterstore("destination", "key", "key1");
			redisCommands.zunionstore("destination", "key", "key1");
			// ...等等
			*/
			
			
			// async:异步非阻塞		********************************************************************************************
			// 操作类似sync,只不过返回结果都是RedisFuture
			/*
			redisAsyncCommands = connection.async();
			
			RedisFuture redisFuture = redisAsyncCommands.ping();	// 此处不会阻塞
			System.out.println("Ping result: " + redisFuture.get());		// get方法获取结果时,此处会阻塞
			
			// redisFuture.get(60, TimeUnit.SECONDS);
			// redisFuture.getError();
			*/
			
			
			// reactive:反应式		********************************************************************************
			// 操作类似sync,只不过返回结果如果只包含0或1个元素,那么返回值类型是Mono,如果返回的结果包含0到N(N大于0)个元素,那么返回值是Flux
			// Reactor编程可以自己了解下,这里省略了,本人也不太了解
			/*
			redisReactiveCommands = connection.reactive();
			
			redisReactiveCommands.set("key", "value").block();
			redisReactiveCommands.get("key").subscribe(value -> System.out.println("结果:" + value));
			*/
		} catch(Exception e) {
			
			e.printStackTrace();
		} finally {
			
			if(connection != null) {
				connection.close();
			}
			
			if(redisClient != null) {
				redisClient.shutdown();
			}
		}
	}
}

Lettuce sentinel哨兵模式

package com.java.ashare.redis.clients.lettuce;

import java.time.Duration;

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.codec.Utf8StringCodec;
import io.lettuce.core.masterslave.MasterSlave;
import io.lettuce.core.masterslave.StatefulRedisMasterSlaveConnection;

public class LettuceSentinel {

	public static void main(String[] args) {
		
		RedisURI redisURI = null;
		RedisClient redisClient = null;
		StatefulRedisMasterSlaveConnection connection = null;
		RedisCommands redisCommands = null;
		
		try {
			// redis连接信息---哨兵模式(可以提供部分sentinel地址信息,lettuce自动拓扑发现其他节点信息并返回redis主实例)
			redisURI = RedisURI.builder()
					//.withPassword("123456")
					.withSentinel("192.168.78.169", 26379)
					.withSentinel("192.168.78.169", 26380)
					.withSentinel("192.168.78.169", 26381)
					.withSentinelMasterId("mymaster")	// sentinel monitor
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			// redis客户端
			redisClient = RedisClient.create();
			// redis连接
			connection = MasterSlave.connect(redisClient, new Utf8StringCodec(), redisURI);
			// connection.setReadFrom(ReadFrom.SLAVE_PREFERRED);	// 读写分离,spring-data-redis2.1之后支持
			
			redisCommands = connection.sync();
			//redisCommands.set("k11", "v11");
			System.out.println("k11: " + redisCommands.get("k11"));
		} catch(Exception e) {
			
			e.printStackTrace();
		} finally {
			
			if(connection != null) {
				connection.close();
			}
			
			if(redisClient != null) {
				redisClient.shutdown();
			}
		}
	}
}

Lettuce cluster集群模式

package com.java.ashare.redis.clients.lettuce;

import java.time.Duration;
import java.util.Arrays;

import io.lettuce.core.RedisURI;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;

public class LettuceCluster {

	public static void main(String[] args) {
		
		RedisClusterClient redisClusterClient = null;
		StatefulRedisClusterConnection connection = null;
		RedisAdvancedClusterCommands redisCommands = null;
		
		try {
			// redis连接信息---集群模式(可以提供部分节点地址信息,lettuce自动拓扑发现集群中其他节点信息)
			RedisURI redisURI1 = RedisURI.builder()
					//.withPassword("123456")
					.withHost("192.168.78.169")
					.withPort(6379)
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			RedisURI redisURI2 = RedisURI.builder()
					//.withPassword("123456")
					.withHost("192.168.78.169")
					.withPort(6380)
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			RedisURI redisURI3 = RedisURI.builder()
					//.withPassword("123456")
					.withHost("192.168.78.169")
					.withPort(6381)
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			RedisURI redisURI4 = RedisURI.builder()
					//.withPassword("123456")
					.withHost("192.168.78.169")
					.withPort(6382)
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			RedisURI redisURI5 = RedisURI.builder()
					//.withPassword("123456")
					.withHost("192.168.78.169")
					.withPort(6383)
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			RedisURI redisURI6 = RedisURI.builder()
					//.withPassword("123456")
					.withHost("192.168.78.169")
					.withPort(6384)
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			
			// redis客户端
			redisClusterClient = RedisClusterClient.create(Arrays.asList(redisURI1, redisURI2, redisURI3, redisURI4, redisURI5, redisURI6));
			// redis连接
			connection = redisClusterClient.connect();
			
			redisCommands = connection.sync();
			redisCommands.set("k13", "v13");
			System.out.println("k13: " + redisCommands.get("k13"));
		} catch(Exception e) {
			
			e.printStackTrace();
		} finally {
			
			if(connection != null) {
				connection.close();
			}
			
			if(redisClusterClient != null) {
				redisClusterClient.shutdown();
			}
		}
	}
}

Lettuce pipe流水线

package com.java.ashare.redis.clients.lettuce;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.lettuce.core.LettuceFutures;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;

/**
 * lettuce redis pipeline流水线功能
 * 
 * 在正常情况下,lettuce会在API客户端调用命令后立即执行命令,这是大多数普通应用程序所需要的,特别是如果它们依赖于串行接收命令结果。
 * 但是,如果应用程序不立即需要结果或批量上传大量数据,则此行为效率不高。异步应用程序可以覆盖此行为。
 */
public class LettuceBatch {

	public static void main(String[] args) {
		
		RedisURI redisURI = null;
		RedisClient redisClient = null;
		StatefulRedisConnection connection = null;
		RedisAsyncCommands redisAsyncCommands = null;
		
		try {
			// redis连接信息---单机
			redisURI = RedisURI.builder()
					.withHost("192.168.78.169")
					.withPort(6379)
					//.withPassword("123456")
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			// redis客户端
			redisClient = RedisClient.create(redisURI);
			// redis连接
			connection = redisClient.connect();
			// redis命令API接口
			redisAsyncCommands = connection.async();
			
			// 流水线-批处理
			redisAsyncCommands.setAutoFlushCommands(false);		// false:命令不会立即发送到redis服务器执行
			List> futures = new ArrayList>();
			for(int i = 0; i < 10; i++) {
				futures.add(redisAsyncCommands.set("key" + i, "value" + i));
			}
			redisAsyncCommands.flushCommands();					// 发送所有命令到redis服务器执行
			
			// 等待执行结果
			LettuceFutures.awaitAll(60, TimeUnit.SECONDS, futures.toArray(new RedisFuture[futures.size()]));
		} catch(Exception e) {
			
			e.printStackTrace();
		} finally {
			
			if(connection != null) {
				connection.close();
			}
			
			if(redisClient != null) {
				redisClient.shutdown();
			}
		}
	}
}

Lettuce 连接池

package com.java.ashare.redis.clients.lettuce;

import java.time.Duration;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.support.ConnectionPoolSupport;

/**
 * lettuce连接池
 * lettuce使用netty,线程安全可以共享连接,一般情况下无需连接池
 * 
 * 有如下几种情况你不能在线程之间复用连接:
 *   1、请求批量下发,即禁止调用命令后立即flush
 *   2、使用blpop这种阻塞命令
 *   3、事务操作
 *   4、有多个数据库的情况
 */
public class LettuceConnectionPool {

	public static void main(String[] args) {
		
		RedisURI redisURI = null;
		RedisClient redisClient = null;
		GenericObjectPool> pool = null;
		StatefulRedisConnection connection = null;
		RedisCommands redisCommands = null;
		
		try {
			// redis连接信息---单机
			redisURI = RedisURI.builder()
					.withHost("192.168.78.169")
					.withPort(6379)
					//.withPassword("123456")
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			// redis客户端
			redisClient = RedisClient.create(redisURI);
			// redis连接池
			GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
			poolConfig.setMaxTotal(20);
			poolConfig.setMaxIdle(20);
			poolConfig.setMinIdle(0);
			poolConfig.setMaxWaitMillis(60 * 1000);
			// ::是java8提供的关键字,用于访问对象方法、静态方法
			// AsyncConnectionPoolSupport: 	支持异步连接的池化
			// ConnectionPoolSupport:		支持同步连接的池化
			pool = ConnectionPoolSupport.createGenericObjectPool(redisClient::connect, poolConfig);	
			
		    // 获取redis连接
		    connection = pool.borrowObject();
			// redis命令API接口
		    redisCommands = connection.sync();
		    
		    String pong = redisCommands.ping();
			if("PONG".equals(pong)) {
				System.out.println("redis服务正常......");
			}
		} catch(Exception e) {
			
			e.printStackTrace();
		} finally {
			
			if(connection != null) {
				pool.returnObject(connection);
			}
			
			if(pool != null) {
				pool.close();
			}
			
			if(redisClient != null) {
				redisClient.shutdown();
			}
		}
	}
}

Lettuce pub/sub发布订阅

package com.java.ashare.redis.clients.lettuce;

import java.time.Duration;

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.pubsub.RedisPubSubListener;
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
import io.lettuce.core.pubsub.api.sync.RedisPubSubCommands;

/**
 * lettuce redis pub/sub发布订阅
 */
public class LettucePubSub {
	
	public static void main(String[] args) {
		
		RedisURI redisURI = null;
		RedisClient redisClient = null;
		StatefulRedisPubSubConnection connection = null;
		RedisPubSubCommands redisPubSubCommands = null;
		
		try {
			// redis连接信息---单机
			redisURI = RedisURI.builder()
					.withHost("192.168.78.169")
					.withPort(6379)
					//.withPassword("123456")
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			// redis客户端
			redisClient = RedisClient.create(redisURI);
			// redis连接
			connection = redisClient.connectPubSub();
			 
			// redis命令API接口
			redisPubSubCommands = connection.sync();
			redisPubSubCommands.publish("channel", "message");	// 向频道channel发布消息
		} catch(Exception e) {
			
			e.printStackTrace();
		} finally {
			
			if(connection != null) {
				connection.close();
			}
			
			if(redisClient != null) {
				redisClient.shutdown();
			}
		}
	}
}

class Subscriber {
	
	public static void main(String[] args) {
		
		RedisURI redisURI = null;
		RedisClient redisClient = null;
		StatefulRedisPubSubConnection connection = null;
		RedisPubSubCommands redisPubSubCommands = null;
		
		try {
			// redis连接信息---单机
			redisURI = RedisURI.builder()
					.withHost("192.168.78.169")
					.withPort(6379)
					//.withPassword("123456")
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			// redis客户端
			redisClient = RedisClient.create(redisURI);
			// redis连接
			connection = redisClient.connectPubSub();
			// RedisPubSubListener定义接收channel消息的监听器
			connection.addListener(new RedisPubSubListener() {
				
				@Override
				public void unsubscribed(String channel, long count) {
				}
				
				@Override
				public void subscribed(String channel, long count) {
				}
				
				@Override
				public void punsubscribed(String pattern, long count) {
				}
				
				@Override
				public void psubscribed(String pattern, long count) {
				}
				
				@Override
				public void message(String pattern, String channel, String message) {
				}
				
				@Override
				public void message(String channel, String message) {
					
					System.out.println("频道:" + channel + ",消息:" + message);
				}
			});
			
			// redis命令API接口
			redisPubSubCommands = connection.sync();
			redisPubSubCommands.subscribe("channel");	// 订阅频道channel,接收消息
		} catch(Exception e) {
			
			e.printStackTrace();
		} finally {
			
			if(connection != null) {
				connection.close();
			}
			
			if(redisClient != null) {
				redisClient.shutdown();
			}
		}
	}
}

Lettuce 事务

package com.java.ashare.redis.clients.lettuce;

import java.time.Duration;

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.TransactionResult;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;

/**
 * lettuce redis事务
 */
public class LettuceTransaction {

	public static void main(String[] args) {
		
		RedisURI redisURI = null;
		RedisClient redisClient = null;
		StatefulRedisConnection connection = null;
		RedisCommands redisCommands = null;
		
		try {
			// redis连接信息---单机
			redisURI = RedisURI.builder()
					.withHost("192.168.78.169")
					.withPort(6379)
					//.withPassword("123456")
					.withDatabase(0)
					.withTimeout(Duration.ofSeconds(60))
					.build();
			// redis客户端
			redisClient = RedisClient.create(redisURI);
			// redis连接
			connection = redisClient.connect();
			// redis命令API接口
			redisCommands = connection.sync();
			
			try {
				redisCommands.watch("key");
				redisCommands.multi();							// 开启事务
				redisCommands.set("key", "value");				// exec执行之前返回null
				redisCommands.set("key1", "value1");
				TransactionResult transactionResult = redisCommands.exec();		// 提交事务
				String firstResult = transactionResult.get(0);	// 第1条命令执行结果
				String secondResult = transactionResult.get(1);	// 第2条命令执行结果
				System.out.println("命令执行结果:" + firstResult + ", " + secondResult);
			} catch(Exception e) {
				redisCommands.discard();						// 回滚事务
				throw e;
			}
		} catch(Exception e) {
			
			e.printStackTrace();
		} finally {
			
			if(connection != null) {
				connection.close();
			}
			
			if(redisClient != null) {
				redisClient.shutdown();
			}
		}
	}
}

你可能感兴趣的:(6、Redis Lettuce实战(含Spring Boot))