search

Home  >  Q&A  >  body text

php - How to use Redis to solve the problem of repeated data insertion into MySQL caused by concurrency?

Business scenario

There is a query system. When the user queries, if there is no data in the database, he needs to call a third-party query interface to obtain the data, then insert the data into the database, and then retrieve the data from the database and return it to the user. [The system is developed based on PHP]

Problem description

If multiple users query, there will be multiple requests to the third-party interface for query at the same time, and the problem of repeated data insertion will arise.

How to solve this problem?
When calling a third-party interface, use Redis to ensure that only one request goes to the third party, thereby avoiding repeated query and insertion of data. Is there any other good method? ? How to achieve it specifically?
Thank you!

淡淡烟草味淡淡烟草味2777 days ago716

reply all(4)I'll reply

  • 伊谢尔伦

    伊谢尔伦2017-05-16 13:03:48

    Lock mechanism. Before the code enters the operation, check whether the operation is locked. If it is locked, interrupt the operation. Otherwise, proceed to the next operation. The first step is to lock the operation, then execute the code. After executing the code, don't forget to unlock the operation lock. Otherwise, you won’t be able to carry out the execution.

    There are many locking codes, and the one given above is one of them. Redismemcachecache files can be used. If the concurrency of operations is relatively high, it is recommended to use redis like the one above. (In fact, it is to use the string data type to assign a value to the lock key {lock}, and when unlocking, the value of the key will be cleared or assigned a value of 0)

    $lock_status = $redis->get('lock_state');
    if ($lock_status == 0 || empty($lock_status)) {
        $redis->set('lock_state', 3600, 1); #操作上锁
        #操作代码
        $redis->set('lock_state', 3600, 0); #操作解锁
    } else {
        #上锁后的操作
    }

    reply
    0
  • 为情所困

    为情所困2017-05-16 13:03:48

    //定义锁的时间秒数
    $lockSecond = 5;
    
    //获取锁定状态
    $lockKey="xxx";
    $lockStatus = $redis->get($lockKey);
    
    if ($lockStatus == 0 || empty($lockStatus)) {//无锁
        //1.上锁
        $redis->set($lockKey, 1, ['nx', 'ex' => $lockSecond]); 
        //2.业务操作
        
        //3.解锁
        $redis->del($lockKey);
    } else {
        sleep($lockSecond);
         //恢复业务操作
       
    }

    reply
    0
  • 高洛峰

    高洛峰2017-05-16 13:03:48

    if (true == $redis_handle->set($lock_key, 1, array('nx', 'ex' => 6))) {
         //插入
    }

    reply
    0
  • 迷茫

    迷茫2017-05-16 13:03:48

    The redis "lock" mentioned by the poster is of course feasible
    In addition, can a unique ID be set for the queried data? This is double verification

    reply
    0
  • Cancelreply