分布式锁实现一. 利用Mysql数据库update锁

文章目录

  • 分布式锁
    • 1、什么是分布式锁:
    • 2、分布式锁应该具备哪些条件:
  • 基于数据库的分布式锁
    • 代码传送
    • 代码运行


分布式锁

1、什么是分布式锁:

分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是,分布式系统中竞争共享资源的最小粒度从线程升级成了进程。

2、分布式锁应该具备哪些条件:

在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
高可用的获取锁与释放锁
高性能的获取锁与释放锁
具备可重入特性(可理解为重新进入,由多于一个任务并发使用,而不必担心数据错误)
具备锁失效机制,即自动解锁,防止死锁
具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败

基于数据库的分布式锁

核心代码

@Slf4j
@Component
public class ScheduleJob
{
    private String key = "job001";
    
    @Autowired
    JdbcTemplate jdbcTemplate;
    
    String ip;
    
    /**
     * 初始化
     */
    @PostConstruct
    public void init()
    {
        long count = jdbcTemplate.queryForObject("SELECT count(*) FROM t_schedule_lock WHERE key_name=?", Long.class, key);
        if (count == 0)
        {
            jdbcTemplate.update("INSERT INTO t_schedule_lock(key_name, time) VALUES(?, now())", key);
        }
        try
        {
            ip = InetAddress.getLocalHost().getHostAddress();
        }
        catch (UnknownHostException e)
        {
        }
    }
    
    @Scheduled(cron = "0/10 * * * * ?")
    public void run()
    {
        try
        {
            if (getLock(9L))
            {
                log.info("[{}] #### hello world ***********", ip);
            }
            else
            {
                log.info("[{}] 没抢到,骂骂咧咧的走了......", ip);
            }
        }
        catch (Exception e)
        {
            log.error(e.getMessage(), e);
        }
    }
    
    /**
     * 获取lock,并更新time为下次执行时间 now()+ seconds
* * 注意: 为了保证jdbcTemplate.update执行成功,一般设置seconds稍小于@Scheduled设置的运行间隔秒数 * * @return */
private boolean getLock(long seconds) { return jdbcTemplate.update("UPDATE t_schedule_lock SET time = adddate(now(), INTERVAL ? SECOND) WHERE key_name = ? AND now() > time", seconds, key) > 0; } }

代码传送

https://gitee.com/00fly/effict-side/tree/master/springboot-schedule

项目已经实现了maven插件打包镜像,上传阿里云镜像仓库。

代码运行

下载docker文件下的这2个文件,上传至带有docker-compose以及docker环境的服务器
在这里插入图片描述
运行命令

sh scale.sh

docker ps

docker logs -f <containerId>

运行效果图:
分布式锁实现一. 利用Mysql数据库update锁_第1张图片
有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-

你可能感兴趣的:(系统架构,系统架构,java)