库存不足,抛出异常之后,数据仍然被写进数据库

库存不足,抛出异常之后,数据仍然被写进数据库

抛出"java.lang.RuntimeException: 订单创建失败,原因:库存不足"之后,订单仍然被写进数据库了,事务没有回滚.排查了很久,没找到怎么回事.

正在回答

登陆购买课程后可参与讨论,去登陆

2回答

我刚在我这里测试了一下,3种情况,serviceA调用ServiceB都可以进行回滚,

http://img1.sycdn.imooc.com//climg/5ec39d570944336915760652.jpg

  1. 除零异常

  2. 手动抛出异常

  3. 自定义异常

这三种都可以回滚。

只有不加@Transactional的时候,才会不回滚。


  • 慕用6772589 提问者 #1
    我他妈崩溃了,昨天一天都是事务失效,今天再试就好了.
    2020-05-20 09:43:04
提问者 慕用6772589 2020-05-19 11:11:56

/**
* @param orderBO :
* @Description: 创建订单
* @return: null
* @Author: 张建 (119855181@qq.com)
* @date: 2020/5/13
*/
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void create(OrderBO orderBO) {
    String userId=orderBO.getUserId();
    String itemSpecIds=orderBO.getItemSpecIds();
    String addressId=orderBO.getAddressId();
    Integer payMethod=orderBO.getPayMethod();
    String leftMsg=orderBO.getLeftMsg();
    Orders orders= new Orders();
    String sid = Sid.nextShort();
    orders.setId(sid);
    orders.setUserId(userId);
   // 包邮费用设置为0
   Integer postAmount = 0;
   orders.setPostAmount(postAmount);
   orders.setPayMethod(payMethod);
   orders.setLeftMsg(leftMsg);
   orders.setIsComment(YesOrNo.NO.type);
   orders.setIsDelete(YesOrNo.NO.type);
   orders.setCreatedTime(new Date());
   orders.setUpdatedTime(new Date());

   //查询地址快照
    UserAddress address=userAddressService.queryAddress(userId,addressId);
    orders.setReceiverName(address.getReceiver());
    orders.setReceiverMobile(address.getMobile());
    orders.setReceiverAddress(address.getProvince()+address.getCity()+address.getDistrict()+address.getDetail());
   //查询商品规格,计算商品总价格和实际支付价格
   String[] splits = itemSpecIds.split(",");
   //TODO 整合redis后,从缓存的购物车里获取购买的商品数量,这里先统一设置为1.
   int number = 1;
   //商品累积金额
   int amount = 0;
   //商品实付金额
   int payAmount=0;
   for(String specId:splits)
   {
       //1.累加商品价格和实际支付金额
       //1.1根据商品规格id查询商品规格
       ItemsSpec itemsSpec = itemsService.querySpecById(specId);
       amount += itemsSpec.getPriceNormal();
       payAmount += itemsSpec.getPriceDiscount();
       //2.根据商品id获取商品信息和主图
       String itemId = itemsSpec.getItemId();
       Items item = itemsService.queryItemById(itemId);
       String itemsMainImg=itemsService.queryItemMainImgById(itemId);
       //3.循环保存子订单到数据库
       String subOrderId = Sid.nextShort();
       OrderItems subOrderItems = new OrderItems();
       subOrderItems.setId(subOrderId);
       subOrderItems.setOrderId(sid);
       subOrderItems.setItemId(itemId);
       subOrderItems.setItemImg(itemsMainImg);
       subOrderItems.setItemName(item.getItemName());
       subOrderItems.setItemSpecId(specId);
       subOrderItems.setItemSpecName(itemsSpec.getName());
       subOrderItems.setPrice(itemsSpec.getPriceDiscount());
       subOrderItems.setBuyCounts(number);
       int i = orderItemsMapper.insert(subOrderItems);
       // 2.4 在用户提交订单以后,规格表中需要扣除库存
       itemsService.decreaseStock(specId,number);

   }
    orders.setTotalAmount(amount);
    orders.setRealPayAmount(payAmount);
   ordersMapper.insert(orders);
    //保存订单状态
   OrderStatus orderStatus = new OrderStatus();
   orderStatus.setOrderId(sid);
   orderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
   orderStatus.setCreatedTime(new Date());
   orderStatusMapper.insert(orderStatus);
}

  • 你这代码看不出啥问题。另外一个service呢?写在哪里的呀?是和这个一起吗
    2020-05-19 11:23:41
  • 提问者 慕用6772589 回复 风间影月 #2
    这个是扣除商品库存的,写在 itemsService里 /** * @param specId : * @param number : * @Description: 扣除商品的库存 * @return: null * @Author: 张建 (119855181@qq.com) * @date: 2020/5/13 */ @Transactional(propagation = Propagation.REQUIRED) @Override public void decreaseStock(String specId, Integer number) { //synchronized 不推荐,在集群下失效 //锁数据库,不推荐,导致数据库性能低下 //TODO 分布式锁 zookeeper redis 推荐使用 //这里使用乐观锁 int i = itemsMapperCustom.decreaseStock(specId, number); if (i != 1){ throw new RuntimeException("订单创建失败,原因:库存不足"); } }
    2020-05-19 13:12:39
  • 风间影月 回复 提问者 慕用6772589 #3
    看不出什么问题,这代码看似ok。你这样。写一个简单的serviceA,调用serviceB,然后B抛出异常,再看A有没有回滚。
    2020-05-19 13:14:46
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师