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会报错,以此来表示操作超时。

  • 相关阅读:
    c#时间函数
    .NET中的lock(C#版本)
    关于OpenSmtp邮件标题过长,附件名,用户名出现乱码问题的终及解决Dll文件
    Windbg 用法
    使用OpenXML将数据导入到Excel模板中
    Compiere源码workspace的两个配置文件内容
    我学MEF系列(8):MEF+Unity实现可扩展拦截器
    基于插件架构的简单的Winform框架(上)
    我学Flash/Flex(2):AS3读取XML文件内容
    我学Flash/Flex(1):Action Script3.0基础知识
  • 原文地址:https://www.cnblogs.com/ouhaitao/p/11078297.html
Copyright © 2011-2022 走看看