zoukankan      html  css  js  c++  java
  • 记一次工作中遇到的类并发的问题

    前言

      首先说一下业务场景:我们系统中的视频全部存储在第三方的云平台上,我们需要调用其接口来对视频进行操作。由于第三方平台的原因,这个操作可能存在0-30秒的延迟,在这期间如果有其他请求对这个视频进行操作就会出现并发问题(一个视频只允许操作一次)。

      其实这个问题算不上真正的并发问题,不过其类似于并发,所以我把它叫做类并发问题。

    解决方案

        系统是一个分布式系统,所以传统的使用同步队列等同步操作无法使用,所以采用分布式锁解决该问题。分布式锁的实现方式一般有三种:1. 基于数据库的锁;2. 基于Redis的锁;3. 基于ZK的锁。

      关于分布式锁的介绍后续我会写一篇博文,这里由于业务逻辑不需要非常高的可靠性,因为其本身并发量并不高,所以采用最简单的基于数据库的锁。

      数据库锁是利用了数据库的唯一索引,当收到请求时,会把往数据库插入一条数据,如果插入成功则表示获取锁成功,否则失败。流程图如下:

      核心加锁步骤如下:

         1. 首先收到用户请求之后会用向数据库insert一条数据,来获取锁,如果获取成功则表示该视频是第一次操作,开始操作。

        2. 如果获取锁失败则判断操作是否超时,如果超时则会重新对该视频进行一次操作,未超时则不作任何处理。

      PS:这里引入超时的原因是因为如果视频正在被操作,这时候服务器崩了,这样当用户第二次请求操作这个视频时可以重启操作。

      上面两个判断其实使用一条SQL即可完成:

    INSERT INTO lock_table(video_id, STATUS, overtime)
    VALUES
        (#{videoId},#{status},#{overtime})
    WHERE
        NOT EXISTS (
            SELECT
                1
            FROM
                lock_table
            WHERE
                video_id = #{videoId}
            AND CURRENT_TIMESTAMP () < overtime
        )

      当第一次操作该视频时where条件返回true可以正常获取锁,当第二次操作该视频且操作未超时,则where条件返回false,当第二次操作该视频且操作超时,where条件返回true但是SQL会报错,以此来表示操作超时。

  • 相关阅读:
    python开源项目聚合推荐【1】
    python开发--Python实现延时操作的几种方式
    odoo开发笔记 -- 单台物理服务器上,利用docker部署多套odoo应用
    odoo开发笔记 -- odoo官方docker启动原理
    odoo开发笔记 -- odoo官方docker镜像部署
    odoo开发笔记 -- 借助模块queue_job实现异步方法调用
    odoo开发笔记 -- 提高访问安全性的一种方式
    python开发笔记-pymsslq连接操作SqlServer数据库
    运维笔记--Debian/Ubuntu系统离线安装pymssql,连接SqlServer
    python开发笔记-str转字典
  • 原文地址:https://www.cnblogs.com/ouhaitao/p/11078297.html
Copyright © 2011-2022 走看看