private async Task GrabRedPacket(string redPacketId, RedPacketRecord redPacketRecord) { bool?tryAgain; do { var token = Environment.MachineName; if (_client.Database.LockTake(redPacketId, token, TimeSpan.FromSeconds(10))) { try { var redPacket = await _client.HashGetAsync <RedPacket>(nameof(RedPacket), redPacketId); redPacket.RemainingCount--; if (redPacket.RemainingCount >= 0) { redPacketRecord.Id = await _client.StringIncrementAsync($"{nameof(RedPacketRecord)}_ID"); if (redPacket.RemainingCount == 0) { //最后一人 redPacketRecord.Amount = redPacket.RemainingAmount; redPacket.RemainingAmount = 0; } else { //抢到红包最多为剩余人均的2倍 var maxAmount = (redPacket.RemainingAmount / (redPacket.RemainingCount + 1) * 2 - 1); redPacketRecord.Amount = new Random().Next(1, maxAmount); redPacket.RemainingAmount -= redPacketRecord.Amount; } await _client.HashSetAsync(nameof(RedPacket), redPacketId, redPacket); await _client.HashSetAsync(nameof(RedPacketRecord), redPacketRecord.Id.ToString(), redPacketRecord); tryAgain = false; _logger.LogError($"成功抢红包{redPacketRecord.Amount / (100 * 1.0)}元:{redPacketRecord.CreateUser}"); } else { //抢完了 tryAgain = null; _logger.LogError("抢完了"); } } finally { _client.Database.LockRelease(redPacketId, token); } } else { //锁住了,正在抢购中,等待所释放后再次抢 tryAgain = true; await Task.Delay(50); } } while (tryAgain.HasValue && tryAgain.Value); }
public async Task <IActionResult> CreateRedPacketRecord([FromBody] RedPacketRecordViewModel viewModel) { var redPacketRecord = new RedPacketRecord { CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), CreateUser = viewModel.CreateUser, RedPacketId = viewModel.RedPacketId }; var redPacketId = viewModel.RedPacketId.ToString(); await GrabRedPacket(redPacketId, redPacketRecord); return(Ok(redPacketRecord)); }