redis集群若想实现多key的事务控制,可能根据分片算法会分配到不同的jedisclient,导致无法进行事务控制,这应该就是redis集群不支持事务的核心原因。但是若是单个key的get()获取值之后再set(),可以使用单个jedis连接的watch、multi()、exec()来实现,防止get()之后其它client又set()导致数据和预期不一致的场景。
redis实现事务方式三种:
1: 跟spring结合事务,只单台redis支持,redis集群就无法满足。
2:使用redis自己本身事务,本文就是。
3:自定义实现方式,可以通过队列实现,手动提交,手动回滚。
基于spring cloud 项目使用redis本身事务配置如下:
首先获取redis集群配置的服务器与端口:
/**
* RedisClusterProperties获取redis集群配置
* @ClassName: RedisClusterProperties
* @date: 2019-1-28
* @Copyright: 2019
*/
@Configuration
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class RedisClusterProperties {
//集群节点
private List<String> nodes=new ArrayList<>();
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
}
JedisCluster配置
/**
* JedisCluster配置
* @ClassName: JedisClusterConfig
* @date: 2019-1-28
*/
@Configuration
public class JedisClusterConfig {
@Autowired
private RedisClusterProperties redisClusterProperties;
@Bean("jedisCluster")
public JedisCluster redisCluster(){
if(redisClusterProperties.getNodes().size()<=0) {
return null;
}
String[] serverArray = redisClusterProperties.getNodes().get(0).split(",");
Set<HostAndPort> nodes = new HashSet<>();
for (String node:serverArray){
String[] parts= node.split(":") ;
Assert.state(parts.length==2, "redis node shoule be defined as 'host:port', not '" + Arrays.toString(parts) + "'");
nodes.add(new HostAndPort(parts[0], Integer.valueOf(parts[1])));
}
return new JedisCluster(nodes);
}
}
调用的工具类:
/**
* @Description: redis集群事物
* @ClassName: JedisClusterTransactionManager
* @date: 2019/1/29
* @Copyright: 2019
*/
public class JedisClusterTransactionManager {
private static ThreadLocal<Object> txThread