mysql update if 事务_mysql update 库存解决并发卖超的问题失败了 where and 真的可行吗?...

在秒杀场景中,使用MySQL的`UPDATE`语句减库存可能存在并发问题。即使库存为0,`WHERE`子句过滤掉了无效操作,但在同一个事务内,后续的订单创建仍可能导致超卖。解决方案通常涉及分布式事务或乐观锁机制来确保数据一致性。
摘要由CSDN通过智能技术生成

16

201 天前

@limuyan44 代码有好几层,那我贴一下

MiaoshaController.java

@RequestMapping(value="/do_miaosha", method= RequestMethod.POST)

@ResponseBody

public Result miaosha(Model model,MiaoshaUser user,

@RequestParam("goodsId")long goodsId) {

model.addAttribute("user", user);

if(user == null) {

return Result.error(CodeMsg.SESSION_ERROR);

}

//判断库存

GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);//10 个商品,req1 req2

int stock = goods.getStockCount();

if(stock <= 0) {

return Result.error(CodeMsg.MIAO_SHA_OVER);

}

//判断是否已经秒杀到了

MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);

if(order != null) {

return Result.error(CodeMsg.REPEATE_MIAOSHA);

}

//减库存 下订单 写入秒杀订单

OrderInfo orderInfo = miaoshaService.miaosha(user, goods); //我提问的操作在这个函数里面

return Result.success(orderInfo);

}

MiaoshaService.java 中,上文的 miaoshaService.miaosha

@Transactional

public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) {

//减库存 下订单 写入秒杀订单

goodsService.reduceStock(goods);

//order_info maiosha_order

return orderService.createOrder(user, goods);

}

GoodsService.java 中,上文的 goodsService.reduceStock

public void reduceStock(GoodsVo goods) {

MiaoshaGoods g = new MiaoshaGoods();

g.setGoodsId(goods.getId());

goodsDao.reduceStock(g);

}

GoodsDao.java 中,上文的 goodsDao.reduceStock

@Update("update miaosha_goods set stock_count = stock_count - 1 where goods_id = #{goodsId} and stock_count > 0")

public int reduceStock(MiaoshaGoods g);

OrderService 上上上段代码最后一句,中的 orderService.createOrder

@Transactional

public OrderInfo createOrder(MiaoshaUser user, GoodsVo goods) {

OrderInfo orderInfo = new OrderInfo();

orderInfo.setCreateDate(new Date());

orderInfo.setDeliveryAddrId(0L);

orderInfo.setGoodsCount(1);

orderInfo.setGoodsId(goods.getId());

orderInfo.setGoodsName(goods.getGoodsName());

orderInfo.setGoodsPrice(goods.getMiaoshaPrice());

orderInfo.setOrderChannel(1);

orderInfo.setStatus(0);

orderInfo.setUserId(user.getId());

long orderId = orderDao.insert(orderInfo);

System.out.println();

MiaoshaOrder miaoshaOrder = new MiaoshaOrder();

miaoshaOrder.setGoodsId(goods.getId());

miaoshaOrder.setOrderId(orderId);

miaoshaOrder.setUserId(user.getId());

orderDao.insertMiaoshaOrder(miaoshaOrder);

redisService.set(OrderKey.getMiaoshaOrderByUidGid, ""+user.getId()+"_"+goods.getId(), miaoshaOrder);

return orderInfo;

}

我觉得这两句话虽然在一个事务里,但是第一句里用了 where,虽然库存已经没了,但是没有报异常,导致 return 那句的订单还是可以生成。

//减库存 下订单 写入秒杀订单

goodsService.reduceStock(goods);

//order_info maiosha_order

return orderService.createOrder(user, goods);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL中,当使用UPDATE语句进行并发更新时,不是所有的UPDATE语句都会全程加锁。根据引用中的解释,在某些情况下,一条UPDATE语句实际上会被拆解成多条SQL语句。例如,假设有以下的伪代码: a = SELECT * FROM table1 WHERE id=1; UPDATE table1 SET num = a.num + 1; 这个例子中,实际上有两条SQL语句,其中一条是SELECT语句用于获取需要更新的值,另一条是UPDATE语句用于更新表中的数据。 另外,引用提到了一个具体的例子,假设有一个名为vip_member的表,当会员想要续买会员时,需要满足一定的业务要求。在这个例子中,使用UPDATE语句时,可以通过设置条件来限制并发更新的条件,例如通过判断end_at是否早于当前时间来设置start_at。 综上所述,使用MySQLUPDATE语句进行并发更新时,可以根据业务需求设置条件来限制更新的范围。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [MySQL并发更新数据时的处理方法](https://download.csdn.net/download/weixin_38653443/13704095)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [MySQL中SELECT+UPDATE处理并发更新问题解决方案分享](https://download.csdn.net/download/weixin_38720997/13690875)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [基于IDEA+Maven+SSM框架+mysql的高并发的商品秒杀项目](https://download.csdn.net/download/qq_35831906/88227624)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值