Esempio n. 1
0
 public ProductService()
 {
     Db = new StorageDatabaseContextFactory().Create();
 }
        public void Reserve(ReserveReq req)
        {
            if (req.IsNull())
            {
                throw new ArgumentNullException(nameof(req));
            }
            if (req.ProductId.IsEmpty())
            {
                throw new ArgumentException(nameof(req.ProductId));
            }
            if (req.Quantity <= 0)
            {
                throw new ArgumentException(nameof(req.Quantity));
            }

            try
            {
                TransactionOptions transOpt = new TransactionOptions
                {
                    IsolationLevel = IsolationLevel.Serializable
                };

                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, transOpt))
                {
                    using (var context = new StorageDatabaseContextFactory().Create())
                    {
                        string sqlQuery = $"SELECT * FROM [ExpressShop.Storage].[dbo].[EntProducts] WITH (UPDLOCK) WHERE Id = '{req.ProductId}'";

                        var product = context.Products
                                      .SqlQuery(sqlQuery)
                                      .FirstOrDefault();

                        Logger.Write($"{Thread.CurrentThread.Name}. Получение товара из бд. Текущий остаток: {product.TotalQuantity}");
                        Logger.Write($"{Thread.CurrentThread.Name}. Запрос товара. Количество: {req.Quantity}");

                        if (product.TotalQuantity == 0)
                        {
                            Logger.Write($"{Thread.CurrentThread.Name}. Товар закончился");

                            scope.Complete();
                            return;
                        }
                        else if (product.TotalQuantity - req.Quantity < 0)
                        {
                            Logger.Write($"{Thread.CurrentThread.Name}. Количество товара, запрошенное для бронирования, больше чем есть на складе");

                            scope.Complete();
                            return;
                        }
                        else
                        {
                            product.TotalQuantity -= req.Quantity;

                            var reservation = new EntReservation
                            {
                                Id = Guid.NewGuid(),
                                Characteristics = product.Characteristics,
                                ProductId       = product.Id,
                                Quantity        = req.Quantity,
                                OwnerId         = Guid.NewGuid()
                            };

                            context.Reservations.Add(reservation);

                            context.SaveChanges();

                            Logger.Write($"{Thread.CurrentThread.Name}. Создание бронирования");
                            Logger.Write($"{Thread.CurrentThread.Name}. Сохранение товара. Остаток: {product.TotalQuantity}");
                        }
                    }

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                Logger.Write($"{Thread.CurrentThread.Name}. Произошла ошибка при бронировании товара: {ex.Message}");
            }
        }