【JAVA随记】使用redis分布式锁处理不同服务器更新数据冲突的问题

【业务场景】

项目部署在两台服务器上,现在要实现数据实时更新的功能,如何避免两台服务器高并发情况下重复更新数据的问题?

【解决办法】

使用redis分布式锁,一台服务器更新时,另一台被阻塞无法进行更新操作

【代码实现】

pom.xml导入redis依赖

<!--redis-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

@Component
public class DateUpdateConfig {

    private static final String LOCK_KEY = "data-update-lock";//锁名称
    private static final String LOCK_VALUE = "locked";//值
    private static final int LOCK_EXPIRE_SECONDS = 60;//时间

    //创建锁
    private Jedis jedis = new Jedis("localhost", 6379);
    public boolean releaseLock() {
        //高并发防止被误删
        String releaseLock = "if redis.call('get',KEYS[1])==ARGV[1] then " + "return redis.call('del',KEYS[1])" +   "else" + "return 0" + "end";
        String lockHolder = jedis.get(LOCK_KEY);
        if (LOCK_VALUE.equals(lockHolder)) {
            Long code = (Long) jedis.eval(releaseLock, 1, LOCK_KEY, LOCK_VALUE);
            return code == 1;
        }
        return false;
    }

    private void updateDataInDatabase() {
        // 执行数据更新操作
    }
    public void updateData() {
        // 获取分布式锁
        String result = jedis.set(LOCK_KEY, LOCK_VALUE, SetParams.setParams().nx().ex(LOCK_EXPIRE_SECONDS));
        // 判断是否成功获取到锁
        if (result != null && result.equalsIgnoreCase("OK")) {
            try {
                // 执行数据更新操作
                updateDataInDatabase();
            } finally {
                releaseLock();
            }
        } else {
            // 锁已被其他服务器获取,跳过任务执行
            System.out.println("获取锁失败");
        }
    }
}

有任何问题欢迎指正!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值