Ask a question of concurrent seating?

< H1 > problem description < / H1 >

I use the hash table to represent the people on the seat (key represents the seat position, value is the specific uid), and then use hsetnx to process the concurrent seat.
but there is a problem that, after the seat is successful, I have to deliver this message to the message queue (to notify the client), but there may be network reasons (or other reasons).
causes the delivery to fail, but redis has no transaction and cannot be rolled back. In this way, there will be problems. I don"t know if you have any good ideas. I take the liberty of asking for advice. The
pseudocode looks like this:

res =  cache.setnx(pos, uid)
if (!res) {
    throw new Exception("")
}
mq.send({
    pos: pos,
    uid: uid,
    time: new Date()
})
Apr.18,2022

the message queue itself is decoupled, so if delivery fails and rollback is equivalent to strong dependency?


you still need to look at this problem in terms of specific scenarios.

    Check the data before the
  1. operation. Try to make sure that subsequent failures are caused by the network.
  2. consider retrying message delivery. If the first delivery fails, then delay 2S and continue the delivery. If it still fails, delay 4 S delivery. Set a retry limit and add log output to the retry process, preferably with an alarm. If it still fails in the end, intervene by hand. For this kind of compensation, you can consider the new goroutine asynchronous processing.
  3. if you must roll back to redis. You can consider locking the whole process yourself to ensure that the value of key in map will not be modified by other requests. When the delivery fails, delete the data in redis. And be sure to judge the deleted data before deletion to ensure that what is deleted must be written by yourself.
  4. To continue the topic of
  5. 3, you can see if redis's set command is appropriate: SET key value [expiration EX seconds | PX milliseconds] [NX | XX] . It not only realizes the function of setnx, but also adds the expiration time. The only difference from map is that there is no unified management of key values.
  6. consider using MySQL transaction substitution. The data table creates four fields, the primary key ID,key,value,status. Set key as the unique index. The first time INSERT inserts data can also simulate the operation of SETNX.

is for reference only and needs to be dealt with according to actual needs


since we are worried about network problems, if we fail to deliver a message (we can take advantage of the confirm mode of rabbitmq ), we will store the message locally, and then start a scheduled task to re-deliver the undelivered message periodically until it is delivered successfully (to ensure the final consistency).
res =  cache.setnx(pos, uid)
if (!res) {
    throw new Exception('')
}
mq.confirmSelect();
mq.send({
    pos: pos,
    uid: uid,
    time: new Date(),
    confirmCallback:function() {
        //
    }
})
Menu