und*_*dog 19 java database concurrency multithreading thread-safety
对不起,如果这个问题可能看起来很幼稚,但我遇到过需要管理电子商务商店数据库中产品数量的情况.
有一个带有整数变量的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
}
Run Code Online (Sandbox Code Playgroud)
从代码中可以清楚地看出,我需要对数据库中的产品计数进行并发检查,以防止丢失更新.
此外,如果多个用户尝试在数据库中仅添加单个左侧产品.应该将产品添加到哪个用户的购物车?
我对此做了一点研究
我找到的可能方法是
为Product创建单例类.这将确保整个应用程序中只有一个产品实例可用.
同步addProductToCart
& removeTheProductFromTheCart
方法.这将只允许一个线程更新产品计数并一次更新数据库.
使用数据库并发控制应用一些db事务隔离级别,乐观/悲观锁定productCount
.我使用mysql的默认隔离级别是REPEATABLE_READ
.
处理这个问题的最佳方法是什么?
3.使用数据库并发控制
为什么?
如果您的电子商务应用程序绝对是修改产品数量的唯一方法,则1和2都可以.这是一个很大的问题.在开展业务和维护库存的过程中,商店可能需要其他方式来更新产品数量,电子商务应用程序可能不是理想的解决方案.另一方面,数据库通常更容易挂钩到有助于商店库存过程的不同应用程序.
数据库产品通常具有许多故障安全机制,因此如果出现问题,您可以跟踪哪些事务成功,哪些事务没有,并且您可以回滚到特定时间点.漂浮在内存中的java程序没有开箱即用的功能,你必须自己开发它,如果你做了1或2. Spring和Hibernate以及其他类似东西肯定比什么都好,只比较它们提供什么和什么数据库提供了从某些电子灾难中恢复的能力.
对于您正在考虑的前两种可能性,只有当您仅限于部署应用程序的单个实例时,它们才有效。您无法跨多个应用程序实例管理单例,也无法跨多个 JVM 进行同步。因此,如果您选择其中之一,您的部署选项将受到限制,部署应用程序的多个实例的唯一方法是执行将会话固定到特定实例之类的操作,这不利于负载平衡。所以这两者似乎都是不可取的。
从数据库获取产品数量的方法的优点是,当您的应用程序跨多个实例扩展时,该方法仍然有效,而不会扰乱负载平衡。
您可能会认为,这只是一台服务器上的一个实例,所以我可以解决这个问题。但在构建应用程序时,可能并不完全清楚应用程序将如何部署(我曾经遇到过这样的情况,直到在预生产环境中设置应用程序时我们才知道计划是什么) ,或者稍后可能有理由更改应用程序的部署方式;如果您的应用程序的负载超出预期,那么设置第二个盒子可能会有所帮助。
我不明白的一件事是产品计数实际上正确是多么重要。在不同的业务领域(机票、航运),超额预订很常见,保持 100% 准确的计数可能会带来更多麻烦,而不是值得,特别是在流程的早期阶段,例如在购物中添加商品购物车(与客户实际承诺购买的时间点相比)。当客户购买商品时,确保您通过数据库事务预订这些商品可能更有意义(或不预订,再次参见超额预订)。
在 Web 应用程序中,预期从购物车中的商品到实际购买的商品的转化率较低似乎很常见。请记住什么级别的计数准确度适合您的业务领域。
归档时间: |
|
查看次数: |
1778 次 |
最近记录: |