使用jedis集群同时对一条记录进行读写事务控制

发布于 2021-11-27 13:57:54 字数 2774 浏览 826 评论 2

服务器:redis-3.0.0.

客户端:jedis-2.6.2

目前我的代码实现是在一台redis服务器上面可以,但是如果是集群的情况下,JedisCluster类里面没有提供事务控制相关方法,请问怎么在集群下对一个key进行事务控制

代码:

import java.util.Date;
import java.util.List;


import org.apache.commons.lang.StringUtils;


import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;


import com.iduanyingjie.redis.businessno.dao.SysBusinessNoDao;
import com.iduanyingjie.redis.businessno.entity.SysBusinessNo;
import com.iduanyingjie.redis.businessno.util.DateUtil;
import com.iduanyingjie.redis.businessno.util.JedisPoolUtil;


public class BusinessNoManager {

    private static final String UNDERLINE = "_";

    // type和orgcode用来确定一个key
    public static String generateBussinessNo(String type, String orgCode) {
        JedisPool pool = JedisPoolUtil.getPool();//获取连接池
        Jedis jedis = pool.getResource();

Integer bn = forGenerate(type + UNDERLINE + orgCode, pool, jedis);

pool.returnResource(jedis);
return String.valueOf(bn);
}


private static Integer forGenerate(String key, JedisPool pool, Jedis jedis) {
jedis.watch(key);
String value = jedis.get(key);


Integer bn = null;
if (value == null) {

SysBusinessNoDao dao = new SysBusinessNoDao();

String[] arr = key.split(UNDERLINE);
String type = arr[0];
String orgCode = arr[1];
// 从数据库中获取这个key的记录
SysBusinessNo sysBusinessNo = dao.getSysBusinessNo(type, orgCode);
if (sysBusinessNo == null) {
value = DateUtil.getYear() + UNDERLINE + 1;
}
else {
value = DateUtil.getYear() + UNDERLINE + sysBusinessNo.getBusinessNo();
}
// set into redis
Transaction tx = jedis.multi();
tx.set(key, value);
tx.exec();
jedis.unwatch();
//
bn = forGenerate(key, pool, jedis);
}


if (StringUtils.isNotBlank(value)) {
String[] arr = value.split(UNDERLINE);
String year = arr[0];
String businessNo = arr[1];
bn = Integer.valueOf(businessNo);


Transaction tx = jedis.multi();
tx.set(key, year + "_" + String.valueOf(bn + 1));
List<Object> result = tx.exec();
//如果提交失败,从新获取,在事务中有可能其他线程操作了这个key
if (result == null) {
// System.out.println(Thread.currentThread() + " failure...");
bn = forGenerate(key, pool, jedis);
} else {
// System.out.println(Thread.currentThread() + " success...");
jedis.unwatch();
}
}
return bn;
}


}


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃颗糖壮壮胆 2021-11-28 21:47:23

可以通过redis对脚本语言lua支持来实现事务,因为脚本执行对于redis来说是原子性的。

妖妓 2021-11-28 21:19:28

redis集群 不支持事务

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文