管理数据库中的产品计数

如果这个问题看起来很天真,请原谅我,但我遇到了一个场景,我需要管理电子商务商店数据库中的产品数量。

有一个带有整数变量的 Product 类,该变量表示对站点用户可见的数据库中可用产品的数量。现在,这个类由几个线程访问,或者可以说是电子商务网站的多个用户。每个人都在将产品添加或删除到他的购物车中。productCount

正在使用的 ORM 框架处于休眠状态

示例代码

@Entity
@Table
class Product{
   @Column
   private int productCount;

   public void addProductToCart(){
     // decrements the product count by 1 & updates the database
   }

   public void removeTheProductFromTheCart(){
    // increments the product count by 1 & updates the database
   }

从代码中可以清楚地看出,我需要对数据库中的产品计数进行并发检查,以防止丢失更新。

此外,如果多个用户尝试在数据库中仅添加单个剩余产品。应将产品添加到哪个用户的购物车?

我对此做了一些研究

我发现的可能方式是

  1. 为 Product 创建单例类。这将确保整个应用程序中只有一个产品实例可用。

  2. 同步 & 方法。这将只允许一个线程一次更新产品计数和更新数据库。addProductToCartremoveTheProductFromTheCart

  3. 使用数据库并发控制 应用一些数据库事务隔离级别,对 .我正在使用mysql,默认隔离级别是.productCountREPEATABLE_READ

处理这个问题的最佳方法是什么?


答案 1

3. 使用数据库并发控制

为什么?

  • 如果您的电子商务应用程序绝对是修改产品数量的唯一方法,则1和2是可以的。这是一个很大的假设。在开展业务和维护库存的过程中,商店可能需要其他方法来更新产品数量,而电子商务应用程序可能不是理想的解决方案。另一方面,数据库通常更容易挂接到不同的应用程序中,这些应用程序有助于商店的库存流程。

  • 数据库产品通常具有许多故障安全机制,因此,如果出现问题,您可以跟踪哪些事务成功了,哪些没有成功,并且可以回滚到特定时间点。浮动在内存中的java程序没有开箱即用的,如果你做了1或2,你必须自己开发它。Spring和Hibernate以及其他类似的东西肯定总比没有好,但比较它们提供的东西和数据库在从一些电子灾难中恢复方面提供的东西。


答案 2

对于您正在考虑的前两种可能性,这些可能性仅在您仅限于部署应用程序的单个实例时才有效。不能跨多个应用程序实例管理单例,也不能跨多个 JVM 进行同步。因此,如果您使用其中一个部署选项,则部署应用程序的多个实例的唯一方法是执行诸如将会话固定到特定实例之类的操作,这对负载平衡不利。所以这两者似乎都是不可取的。

从数据库获取产品计数的方法具有以下优点:当您的应用程序跨多个实例进行纵向扩展而不会破坏负载平衡时,该方法仍然有效。

你可能会想,这只会是一台服务器上的一个实例,所以我可以做到这一点。但是在构建应用程序时,可能并不完全清楚应用程序将如何部署(我一直处于这样的情况,直到在预推环境中设置应用程序之前,我们不知道计划是什么),或者在以后的某个日期,可能有理由更改应用程序的部署方式;如果您的应用程序具有超出预期的负载,那么设置第二个框可能是有益的。

有一件事对我来说并不明显,那就是产品数量实际上是正确的是多么重要。在不同的业务领域(机票,运输),超额预订很常见,并且可能比保持100%准确的计数更麻烦,特别是如果它是在流程的早期阶段,例如将商品添加到购物车(与客户实际承诺购买的点相比)。在客户购买某些东西时,确保使用数据库事务(或不预订,参见再次超额预订)保留这些项目可能更有意义。

在Web应用程序中,期望从购物车中的项目到实际购买的项目的转化率很低似乎很常见。请记住,您的计数准确度适合您的业务领域。


推荐