使用 FOR UPDATE SKIP LOCKED 处理并发未按预期工作

问题描述 投票:0回答:0

我试图通过并行执行 MySQL 8.0 请求多次来处理提示。我的想法是使用 FOR UPDATE SKIP LOCKED 来避免选择重复的行,所以过程是这样的:

-选择值 = xxx limit 10 FOR UPDATE SKIP LOCKED 的行;

-将10个结果的值改为yyy;

-坚持和冲洗

我有一个 cron 在同一时间段(每分钟)执行此任务 10 次 因此,即使 FOR UPDATE SKIP LOCKED,该任务似乎也选择了相同的行。 这是我的实际要求:

SELECT bill.* 
      FROM billing bill
      JOIN subscriber s ON s.subscriber_id = bill.subscriber_id 
      JOIN subscription sub   ON s.subscriber_id = sub.subscriber_id
                             AND bill.subscription_id = sub.subscription_id
      JOIN (
          SELECT MAX(billing_date) billing_date,
                 subscriber_id,
                 subscription_id
            FROM billing
           WHERE billing_value = 'not_ok BILL010 3'
           GROUP BY subscriber_id, subscription_id
           ) latest   ON bill.subscriber_id = latest.subscriber_id
                     AND bill.subscription_id = latest.subscription_id 
                     AND bill.billing_date = latest.billing_date                 
        WHERE s.status = 'C' 
       AND sub.renewable = 1
       AND sub.store = 'BizaoStore'
       AND bill.billing_value = 'not_ok BILL010 3'
       AND sub.purchase_token IN ('newgamz_cg', 'newgamz_cg_wait' ) 
       AND bill.billing_value IN (
          'not_ok bizao_tobe', 'not_ok BILL010 2', 
          'not_ok BILL010', 'not_ok BILL010 3')
          
        AND bill.billing_date > '2023-04-04 00:00:00'



     ORDER BY sub.created_at DESC
     LIMIT 10 FOR UPDATE SKIP LOCKED;"

我正在使用 symfony 命令来执行这个请求,这里是代码片段:

        $q = $entityManager->createNativeQuery($SQL, $rsm);
        $billings = $q->getResult();
        if($billings) {
            foreach($billings as $billing){
                $billing->setBillingValue("new value");
                try{
                    $entityManager->persist($billing);
                }
                catch (Exception $e){       
                }   
                
                try{
                    $entityManager->flush();
                }catch(Exception $e){
                }
            }
       }

我的 cronjob 每分钟执行此命令 10 次,所以根据我的理解,我应该每分钟获取 10x10 行并更新它们。但这里发生的情况是,同时执行 10 次此请求有时会导致多次更新相同的行。 我没有正确理解什么?

这是我的数据库表:

订阅表

帐单表

订阅者表

php mysql symfony queue locking
© www.soinside.com 2019 - 2024. All rights reserved.