Redis HINCRBY перезаписывает данные внутри повторно заблокированной транзакции - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть функция, которая обновляет баланс пользователя на определенную величину:

export function incrementUsersOpenOrderBalance(order, amount, multi) {
  multi.hincrby('order_sums', `${order.GetUserId()}-${order.coin}`, amount)
}

, которая отлично работает в 99% случаев.Он находится внутри блокировки:

    try {
      lock = await rateLock.lock(`locks:balance:${userId}`, 60000)
      let userBalance = await balancestore.getBalanceForUserId(userId)
      do {
        let multi = redis.multi();
        executedTrades = await placeOrder(orderProcessing, userBalance, multi)
        await completeTradesInTransaction(executedTrades, execMulti)
      } while (1);
    } catch(e) {
       ...
    } finally {
      if (lock) {
        lock.unlock()
        lock = null
      }
    }

(execMulti) вызывает await multi.execAsync()

Внутри много логики, но баланс пользователя обновляется только один раз за вызов.По некоторым причинам он иногда не будет HINCRBY -XXXXXXX и уменьшаться на правильную сумму.Я заметил тенденцию каждый раз, когда это происходит, на самом деле она запускает эту команду HINCRBY -XXXXXXX, затем обрабатывается следующий заказ, а затем баланс пользователя фактически устанавливается на -XXXXXXX.Я предполагаю, что это происходит во время вызова HINCRBY -XXXXXXX, когда вместо обновления его значение перезаписывается.

Я несколько раз запускал redis-cli MONITOR, чтобы посмотреть это несколько раз, и странно то, что все выглядит хорошомне.

1543351721.451263 [0 lua] "set" "locks:balance:userid" "random_value" "NX" "PX" "60000"
1543351721.473371 [0 10.56.5.109:47958] "multi"
1543351721.473533 [0 10.56.5.109:47958] "hincrby" "order_sums" "userid" "-2483395200000"
1543351721.473598 [0 10.56.5.109:47958] "hincrby" "sums" "order-sum" "-3520000"
1543351721.473635 [0 10.56.5.109:47958] "exec"
1543351721.483502 [0 lua] "get" "locks:balance:userid"
1543351721.483543 [0 lua] "del" "locks:balance:userid"
1543351721.485265 [0 lua] "set" "locks:balance:userid" "new_random_value" "NX" "PX" "60000"
1543351721.501101 [0 10.56.5.109:47958] "multi"
1543351721.501331 [0 10.56.5.109:47958] "hincrby" "sums" "order_sum" "-3910000"
1543351721.501376 [0 10.56.5.109:47958] "hincrby" "order_sums" "userid" "-2758544100000"
1543351721.501507 [0 10.56.5.109:47958] "exec"
1543351721.503079 [0 lua] "get" "locks:balance:userid"
1543351721.503104 [0 lua] "del" "locks:balance:userid"

Как видите, он каждый раз блокируется, затем начинает транзакцию с MULTI, выполняет hincrby, затем EXEC, затем снимает блокировку.

После этого он публикует сальдо, а баланс userid устанавливается на -2483395200000.Я заметил это несколько раз.

В основном HINCRBY очень редко перезаписывает данные вместо того, чтобы обновлять их.

...