首页 > 解决方案 > 防止多个用户同时执行查询并重定向到不同的会话 php/mysql

问题描述

我已经创建了日程安排电话。每个时间表都有 1 个独特的会话。在我的情况下,最初的计划会话将为空。如果两个或更多成员想加入计划通话,他们将单击开始按钮。当时我正在检查会话是否存在于表中。如果它是空的,那么我正在生成会话并在数据库中更新会话并返回该会话。

但有时,多个用户同时点击开始按钮,他们会去其他条件并更新不同的会话并返回各自的会话 ID。然后他们将重定向到不同的会议室。那么,即使他们同时单击,我如何才能防止这种情况发生并为所有用户返回相同的会话以进行单个计划调用。

下面是我的代码,当用户单击同一时间时,它们会为用户产生不同的会话。

                   $schInfo = Schedule::where('status', '=', 1)->where('id', '=', $scheduleId)->first();

                        if(isset($schInfo ->session) && !empty($schInfo ->session))
                        {
                            $schedule_session = $schInfo ->session;
                        } else
                        {
                            $schedule_session = CreateSession();
                            $res = Schedule::where('id', $scheduleId)->update(['session' => $schedule_session]);
                        }

                       return $schedule_session;

我已经像下面这样更新了。但我不确定这是正确的解决方案

             $schInfo = Schedule::where('status', '=', 1)->where('id', '=', $scheduleId)->first();

                    if(isset($schInfo ->session) && !empty($schInfo ->session))
                    {
                        $schedule_session = $schInfo ->session;
                    } else
                    {
                        $schedule_session = CreateSession();
                        sleep(rand(1,5));
                        $res = Schedule::where('id', $scheduleId)->whereNull('session')->update(['session' => $schedule_session]);
                        $schInfo = Schedule::where('status', '=', 1)->where('id', '=', $scheduleId)->first();
                        $schedule_session = $schInfo ->session;
                    }

                   return $schedule_session;

在 10 次尝试中的第一个代码片段中,8 次生成不同的会话。使用 10 次或 2 次中的第二个片段生成不同的会话。

请让我知道有什么办法吗?

标签: phpmysql

解决方案


这不是代码解决方案,代码将无法使用。但是,逻辑将是。您的问题是您在排队用户加入呼叫之前存储会话。您应该首先让用户加入队列,然后托管呼叫者每秒钟检查一次队列是否有n参与者(n秒将为多次点击问题留出时间)。然后使用呼叫队列中的第一个参与者生成会话并附加到呼叫。

您需要向参加电话会议的参与者提供反馈,我没有在此提供,但希望您能理解我所说的要点。

前端使用示例:

$(function() {
    // Pull out the first connection in the queue, if any
    var checkIncomingCallConnections = setInterval(function() {
        $.get('/api/calls/incoming', function(response) {
            if(response.hasUser()) {
                // Your logic for updating or creating the call interface
                // ...
                clearInterval(this);
            }
        });
    }, 1000);
    $('#call-btn').click(function() {
        // Generate the queue...
        $.post('/api/calls/outgoing', function(response) {
            // Your logic for updating or creating the call interface
            // ...
            checkIncomingCallConnections();
        });
    });
})(jQuery);

后端使用示例:

$schInfo = Schedule::where('status', '=', 1)->where('id', '=', $scheduleId)->first();

if(isset($schInfo ->session):
    $schedule_session = $schInfo->session;
else:
    $schedule_session = CreateSession();
    $res = Schedule::where('id', $scheduleId)->update(['session' => $schedule_session]);
endif;

return $schedule_session;

API 传出:

Route::post('/calls/outgoing', function() {
    CallQueue::create(referenceAboveCode()); // Should return $schedule_session
});

Route::get('/calls/incoming', function() {
    $queue = CallQueue::list(referenceAboveCode()); // Should return $schedule_session
    // $queue[0] joins the call
    // update database with this session
});

推荐阅读