RTMP协议安防视频直播点播平台EasyDSS点播目录绑定用户接口无响应问题排查

EasyDSS安防视频平台支持视频点播,即用户自行上传视频,使用者可以在点播栏目内自由选择想要观看的视频播放。EasyDSS是TSINGSEE青犀视频云边端架构中唯一支持点播的音视频流媒体平台。

问题描述

在EasyDSS新功能开发过程中,发送绑定用户接口/v1/vodDir/bindUsers,服务器无反馈,并且后台也完全无响应。
前端发送信息如下:

 
### 绑定用户
POST http://localhost:10080/v1/vodDir/bindUsers
Accept: */*
Cache-Control: no-cache
Content-Type: application/json
 
{
  "vodDirID": "N7XKMipMR",
  "bindUserIDs": "["sam"]",
  "unbindUserIDs": "[]"
}

  

请求含义为将 N7XKMipMR 目录绑定到 sam 用户下,但是后台并不会响应该请求,一直未将请求信息打印出来。

该请求在 11:10 分发送,到11:14 分,仍未打印出请求。

原因分析

查看代码,因为是更新数据库操作,所以开启了事务操作。即下文中的 tx,tx 会获取数据库连接,在 tx.Commit() 后才会将连接释放。

tx := impl.fromTable().Begin()

  

在处理过程中,因为需要查询用户是否存在,所以调用下以下代码。

if !gUserDao.Exists(bindUserID) {
   return nil, errors.New("用户 " + bindUserID + " 不存在!")
}

在 gUserDao.Exists() 函数中并未进行事务处理。而是尝试直接获取数据库连接。在EasyDSS中,默认的数据库连接只有一个,此时连接被 tx 已经提前获取了并且不会释放出来,因此在 gUser.Exist() 会一直等待数据库连接被释放,导致程序阻塞在此处。

比喻来说,tx 获取数据库连接池,就像得到一个可以抽取数据库信息的水管,这个水管有且仅有一个,并且同一时间只能被一个人使用。而开启事务,就是在这一段期间独占这一条水管,除非它自己将这个水管移交出去,否则其他任何人都不能获取到这条水管,因此出现以上问题。

解决方案

不采用调用其他函数的方式,而是仍然使用当前的数据库连接获取信息即可,即仍然使用 tx 获取用户的信息,代码如下:

if tx.First(&user, "id = ?", bindUserID).RowsAffected == 0 {
   return nil, errors.New("用户 " + bindUserID + " 不存在!")
}

最终可以正常发送信息,后台也有打印。

EasyDSS视频平台点播界面

原文地址:https://www.cnblogs.com/easydss/p/13954649.html