gpt4 book ai didi

mysql - 如何优化代码作为同步块(synchronized block)在处理多个请求时导致大量延迟

转载 作者:行者123 更新时间:2023-11-29 15:40:12 26 4
gpt4 key购买 nike

我正在编写一些代码,其中有一个库存表,其中包含项目A、B、C,数量为2,1,2

现在多个用户可以调用我的order函数将检查库存状态,如果订单中的所有商品都有货,则订单将完成。

例如我们有order(A:2, B:1) 。当库存中有元素时,可以完成此订单。但如果我们有 order(A:2, B:2) ,那么就不可能满足该顺序,我们可以抛出异常。

现在,在单一请求系统中,上述内容很简单。但实际上我们会有许多并发订单请求,例如 user1 调用 order(A:2, B:1)和 user2 通话 order(B:1, C:2)那么只能满足一个订单,因为 B 商品是两个订单的一部分,并且可用数量 (1) 小于组合订购数量 (2)。

首先我想到了以下代码:

    Class Order{
Map<String, Integer> requestedProducts;
}

// synchronize the order object as we need to have a consistent view of the available inventory
Class test {
public void order(Order o){
synchronized(Order.class) {
// do the database operations
}
}
}

上述方法的明显缺点是对 Order 对象的锁定不是最佳的。

是否有任何其他最佳方法可以实现相同的目标,即可以完成完整订单,或者如果至少缺少一件商品,则订单失败?

在阅读了google上的一些文章后,我可以想到以下另外两种方法:

  • 使用具有适当隔离级别的事务,例如读取已提交,确保当前事务在结束时进行检查是否有任何其他事务未提交与我们相同的数据正在修改。

  • 我可以只使用MYSQL行级锁更新锁定条款。另外请让我知道数据库级锁定是否比代码中完成的代码级锁定更好?

最佳答案

我只是在查看许多不同的资源来找到上述解决方案,我认为最好的解决方案是启动事务并根据订单中请求的产品数量使用行级锁

所以不需要同步锁,它是 JVM 级别的锁,如果我们网站有多个实例在运行,那么同步锁机制就会失败。因此,使用事务和行级锁,代码(伪代码)可能如下所示:

 while(restart the transaction if some error occurs such as timeout)
begin transaction;
String query = "select * from inventory where";
for each(product in requested products){

String productId = product.getProductId();
query += "productid = "+productId;

if(!lastProduct) {
query += "OR"
}
}
query += "FOR UPDATE";

// will lead to lock on the rows due to FOR UPDATE
Resultset rs = execute(query);

forEach(reuslt in resultSet){

if(requested quantity available)
update inventory with updated quantity for the product type in current result of resultSet
}
}

恕我直言,这需要锁定,因为我不知道在给定条件下有任何其他更好的方法(所有项目必须存在才能完成订单)。因此,我们首先需要确保商品存在,并且还需要确保没有其他事务更新我们刚刚读取的相同库存记录,以确保一致性。

如果还有其他更好的方法,请告诉我。

关于mysql - 如何优化代码作为同步块(synchronized block)在处理多个请求时导致大量延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57757721/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com