高并发场景,实现一个判断库存并扣减库存的功能

我理解是防止超卖的一个场景,由于这块是高并发的场景下,频繁操作数据库,会造成性能问题,这块分两部分处理,一部分是从业务层控制冻结库存,从理财货架选择商品点击申购后,跳到收银台提交支付,在提交支付的动作里面进行剩余份额确认,当前我们是进行缓存查询,查询当前的剩余份额>申购份额时,则把这部分份额进行冻结处理,然后首先保证前端显示的剩余库存已被减掉,防止超卖。等支付成功之后,再把真实份额减掉,如果支付失败则释放冻结的份额。

 

另外一部分是底层数据库操作扣减库存逻辑,首先采用事务控制,我们通常会采用try, catch(rollback), commit模式在一个事物里面,在真实更新数据库的库存时,要先进行一个update操作得到真实的扣完剩余库存,再判断该值是否大于0,如果小于0则抛异常进行catch回滚,更新库存失败,保证在高并发下不会导致库存为负数。

 

beginTranse(开启事务)
try{
    //quantity为请求减掉的库存数量
    $dbca->query('update s_store set amount = amount - quantity where postID = 12345');
    $result = $dbca->query('select amount from s_store where postID = 12345');
    if(result->amount < 0){
       throw new Exception('库存不足');
    }
}catch($e Exception){
    rollBack(回滚)
}
commit(提交事务)

 

 

另外,更简洁的方法:

beginTranse(开启事务)
try{
    //quantity为请求减掉的库存数量
    $dbca->query('update s_store set amount = amount - quantity where amount>=quantity and postID = 12345');
}catch($e Exception){
    rollBack(回滚)
}
commit(提交事务)

 

 

我们在数据库层也会采用加锁机制(乐观锁,时间戳或者version)去控制并发修改统一记录的情况。

或者通过服务端的内存锁(锁主键)。当某个用户要修改某个id的数据时,把要修改的id存入memcache,若其他用户触发修改此id的数据时,读到memcache有这个id的值时,就阻止那个用户修改

尽量去减少数据库的大并发读写压力,通过缓存或队列方式降低读写操作。

或者针对产品名称+uid为唯一索引,控制并发。

 



 

 

好的,这个问题可以回答。对于高并发订单扣减库存的问题,需要考虑多线程并发和数据库事务的管理。以下是一个示例代码: ```java public class OrderService { private final InventoryDao inventoryDao; public OrderService(InventoryDao inventoryDao) { this.inventoryDao = inventoryDao; } // 扣减库存,返回值为扣减是否成功 public boolean reduceStock(int itemId, int quantity) { int stock = inventoryDao.getStock(itemId); if (stock < quantity) { return false; } return inventoryDao.reduceStock(itemId, quantity); } } public class InventoryDao { // 获取库存 public int getStock(int itemId) { String sql = "SELECT quantity FROM inventory WHERE item_id = ?"; try (Connection conn = getConnection(); PreparedStatement statement = conn.prepareStatement(sql)) { statement.setInt(1, itemId); try (ResultSet rs = statement.executeQuery()) { if (rs.next()) { return rs.getInt("quantity"); } } } catch (SQLException e) { throw new RuntimeException(e); } return 0; } // 扣减库存,返回值为扣减是否成功 public boolean reduceStock(int itemId, int quantity) { String sql = "UPDATE inventory SET quantity = quantity - ? WHERE item_id = ?"; try (Connection conn = getConnection()) { conn.setAutoCommit(false); try (PreparedStatement statement = conn.prepareStatement(sql)) { statement.setInt(1, quantity); statement.setInt(2, itemId); int affectedRows = statement.executeUpdate(); if (affectedRows == 1) { conn.commit(); return true; } } conn.rollback(); } catch (SQLException e) { throw new RuntimeException(e); } return false; } private Connection getConnection() throws SQLException { // 获取数据库连接 } } ``` 在这个示例代码中,OrderService 是对外提供的服务类,它依赖于 InventoryDao 来管理库存。reduceStock 方法是扣减库存的核心方法,它首先从数据库中获取当前库存数量,然后检查是否足够扣减。如果足够扣减,就开启一个数据库事务,更新库存数量,最后提交事务。如果不足扣减,就直接返回 false 表示扣减失败。 在实际使用中,需要根据具体场景进行优化,比如使用连接池来提高数据库连接的性能,采用分布式锁来控制并发等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值