Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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));
        }