Home  >  Q&A  >  body text

redis - 防同一用户并发操作方案咨询

新客领取优惠券逻辑

同一用户并发领券的情况下 会有超领的情况 因为并发进来时查询数据库均没有领取记录

而又不能针对用户和优惠券做唯一索引 因为有些券允许用户领取多张。

于是决定采用redis计数来防同一用户并发超领 新客领券逻辑改成如下

上述逻辑没有问题 但纠结该如何设置计数key的过期时间

有没其他防并发领取方案呢? 可以不用纠结这种过期时间的设置呢。

滿天的星座滿天的星座2754 days ago845

reply all(5)I'll reply

  • PHP中文网

    PHP中文网2017-04-27 09:04:40

    It is recommended to separate the prevention of over-concurrency and the determination of whether a new customer is a new customer

    • Anti-concurrency super collar can use the following (lock), remember to delete the key (release the lock) after each operation

    // 操作的原子性,如该key在有效时间30秒被设置过返回0,一般请求超时为30秒
    $redis->set($key, 1, array("NX", "EX"=>'30'));
    • To determine whether the user is a new customer (whether the user has received it before, the valid time is set to the end of the event), you can set a new KEY as the user's receiving status. After receiving it, it will be directly returned to the user who has received the discount (when pursuing concurrency performance, No connection to database query)

    • Get the coupon (put the coupon into the queue in advance and get it from the queue, not from the database. The advantage here is that the queue data will be gone once it is retrieved, and there will be no over-receipt situation), and write it into the redis queue

    • Background process consumption queue, I use linked list blocking type for consumption (store the collection information into the database, and query and determine whether the user has received the coupon before entering the database)

    reply
    0
  • 黄舟

    黄舟2017-04-27 09:04:40

    The specific plan still needs to be implemented according to the business

    1. If the business does not require 100%, each person can only receive one coupon, and your Redis cluster is highly available. Then it is enough to block it with Redis. The specific Key expiration time will be invalid after the activity is downloaded. Because this is a solution that does not fall into the database, if you need to determine whether to make repeated requests, you need to rely on the data in Redis (what if Redis crashes? Although Redis has an imperfect persistence function, the amount of data lost is relatively small. If the business allows it, it is still acceptable), but many business scenarios require logging out

    2. Business requirements require that one person must have one coupon (the face value of the coupon may be very large), so the topic owner’s Redis plan should be used in the front. After judging that it is the first time, directly insert/update the database (there will be asynchronous here scheme, but asynchronous schemes will also appear, and asynchronous schemes will also have problems similar to 1: losing data). According to this scheme, it can be guaranteed that each person can only receive one coupon (the database ensures the consistency of the data) . As the questioner said, in fact, you don’t need to invalidate the things in Redis, because if a user repeatedly maliciously requests to draw coupons, Redis can directly block it without going to the database to query (there is another problem here. The solution is to update the cache first. Update the database again, so you need to consider the abnormal situation where the cache update is successful but the database update fails. If the database is abnormal, you need to clear the cache corresponding to the key)

    3. If you really can’t handle it (the hardware can’t keep up), you can use queues to solve the problem and use queues to cut peaks

    4. @大woo's solution is also feasible, but you need to consider this abnormal situation at a certain momentRedis

    5. reply
      0
  • 滿天的星座

    滿天的星座2017-04-27 09:04:40

    @大woo The function mentioned is actually similar to flash sales. I wrote an article before. You can take a look at:
    Essential functions for e-commerce products: flash sales and bidding

    reply
    0
  • 滿天的星座

    滿天的星座2017-04-27 09:04:40

    Isn’t it possible to write a queue?

    reply
    0
  • 淡淡烟草味

    淡淡烟草味2017-04-27 09:04:40

    You dare to use nosql database for this kind of thing. I’m also drunk.

    It is recommended to learn the theory of database first, focusing on the concept of transactions, several isolation levels of transactions, row locks and table locks, and then use a traditional relational database to do this.

    If the performance of a database server is not enough, then design a horizontal table architecture, with different servers, each server responsible for a part of the user data. The theoretical source of the level table is the hash chapter of undergraduate-level data structures. You can take a look at it.

    reply
    0
  • Cancelreply