Vertx的Redis Client进行事务处理

汤飞
2023-12-01

Vertx的Redis Client中主要有两个类

  1. RedisClient
  2. RedisTransaction
其中RedisTransaction是用来处理Redis缓存事务的。

场景:Redis缓存中有个数据 i=100;
有两个操作,都要对i进行+100的处理

如果不做事务处理:
  1. 操作1读Redis缓存i,得到100
  2. 操作2读Redis缓存i,也得到100
  3. 操作1对Redis缓存i进行+100,减200写入到Redis缓存
  4. 操作2对Redis缓存i进行+100,减200写入到Redis缓存
结果可以看到是200,预期是300

所以必须进行事务处理,Vertx的Redis事务处理用的是乐观锁,流程如下:
  1. watch key:先监视某个key
  2. get key:从redis缓存中读取key值
  3. multi:开启事务
  4. set key:对key值进行处理,写入新值到Redis
  5. exec:提交事务,如果key值变了,提交的返回值是null,如果key值没变,返回值为正确执行结果
  6. 如果提交的返回结果是null,重复1~5,由于是乐观锁,原则上会到提交成功为止
  7. 如果发生error,进行异常处理
代码如下:
	public void redisTransaction(Vertx vertx){
		//Redis连接
		RedisOptions  config = new RedisOptions();
		config.setHost("127.0.0.1");
		config.setPort(6379);
		
		RedisClient client = RedisClient.create(vertx, config);
		//Redis缓存事务模块
		RedisTransaction transactionClient = client.transaction();
		transactionClient.watch("i", res->{
			if(!res.succeeded()){
				res.cause().printStackTrace();
			}
		});
		transactionClient.get("i", getRes->{
			if(getRes.succeeded()){
				//开启Redis缓存事务
				transactionClient.multi(multiRes->{
					if(!multiRes.succeeded()){
						multiRes.cause().printStackTrace();
					}
				});
				
				//更新Redis缓存key的值
				Integer value = Integer.parseInt(getRes.result()) + 100;
				
				//同步i到Redis缓存
				transactionClient.set("i", value.toString(), setRes->{
					if(!setRes.succeeded()){
						setRes.cause().printStackTrace();
					}
				});
				
				//执行Redis缓存事务
				transactionClient.exec(res->{
					if(res.succeeded()){
						if (res.result() == null) {
							//乐观锁执行失败,重新执行
							redisTransaction(vertx);
						}
					} else {
						res.cause().printStackTrace();
					}
				});
			} else {
				getRes.cause().printStackTrace();
			}
		});
	}





 类似资料: