一、问题引出
如果关闭订单时如下代码实现的,会引发什么问题?
public void closeOrder(Long orderId, Long userId) {
// int a = 1 / 0 ;
// 根据订单的id查询订单
LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
lambdaQueryWrapper.eq(OrderInfo::getId , orderId) ;
lambdaQueryWrapper.eq(OrderInfo::getUserId , userId) ;
OrderInfo orderInfo = this.getOne(lambdaQueryWrapper);
// 判断订单的状态是否为未支付
if(OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus()) && ProcessStatus.UNPAID.name().equals(orderInfo.getProcessStatus())) {
// 将订单的状态更改为已关闭
// update order_info set order_status = 'CLOSE' , process_status = 'CLOSE' where id = ? and user_id = ?
orderInfo.setOrderStatus(OrderStatus.CLOSED.name());
orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
this.update(orderInfo , lambdaQueryWrapper) ;
}
}
1.订单在支付成功后,将订单状态改正已支付
2.订单超时未支付,将订单状态改为关闭状态
情况一:当订单在支付时,且关闭订单操作进入查询订单操作,然后订单完成支付并且状态更改时,此时判断订单状态是否支付的条件不会成立,这种情况不需要做操作。
情况二:当关闭订单操作并且进入到判断订单状态的提交成立时,此时成功支付,订单状态更改成已支付,然后订单又被更改成已关闭.
情况二的解决方案:1.悲观锁:jdk、分布式锁
2.乐观锁:cas算法
乐观锁原理:cas算法,version版本号
二、解决方案
在进行订单关闭的时候添加上订单未支付的条件
public void closeOrder(Long orderId, Long userId) {
// int a = 1 / 0 ;
// 根据订单的id查询订单
LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
lambdaQueryWrapper.eq(OrderInfo::getId , orderId) ;
lambdaQueryWrapper.eq(OrderInfo::getUserId , userId) ;
OrderInfo orderInfo = this.getOne(lambdaQueryWrapper);
// 判断订单的状态是否为未支付
if(OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus()) && ProcessStatus.UNPAID.name().equals(orderInfo.getProcessStatus())) {
// 将订单的状态更改为已关闭
// update order_info set order_status = 'CLOSE' , process_status = 'CLOSE' where id = ? and user_id = ? and order_status = 'UNPAID' and process_status = 'UNPAID'
orderInfo.setOrderStatus(OrderStatus.CLOSED.name());
orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
lambdaQueryWrapper.eq(OrderInfo::getOrderStatus , OrderStatus.UNPAID.name()) ;
lambdaQueryWrapper.eq(OrderInfo::getProcessStatus , ProcessStatus.UNPAID.name());
this.update(orderInfo , lambdaQueryWrapper) ;
}
}