一、如何使用锁解决电商中的超卖的问题?
1、模拟5个线程并发执行。使用CyclicBarrier类

package com.example.distributedemo; import com.example.distributedemo.service.OrderService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @RunWith(SpringRunner.class) @SpringBootTest public class DistributeDemoApplicationTests { @Autowired private OrderService orderService; @Test public void concurrentOrder() throws InterruptedException { Thread.sleep(60000); CountDownLatch cdl = new CountDownLatch(5); CyclicBarrier cyclicBarrier = new CyclicBarrier(5); ExecutorService es = Executors.newFixedThreadPool(5); for (int i =0;i<5;i++){ es.execute(()->{ try { cyclicBarrier.await(); Integer orderId = orderService.createOrder(); System.out.println("订单id:"+orderId); } catch (Exception e) { e.printStackTrace(); }finally { cdl.countDown(); } }); } cdl.await(); es.shutdown(); } }
二、 基于ReentrantLock锁解决超卖问题(方法锁)
通过手动获取事务,commit 和 rollback 检验库存和扣减库存

package com.example.distributedemo.service; import com.example.distributedemo.dao.OrderItemMapper; import com.example.distributedemo.dao.OrderMapper; import com.example.distributedemo.dao.ProductMapper; import com.example.distributedemo.model.Order; import com.example.distributedemo.model.OrderItem; import com.example.distributedemo.model.Product; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.Date; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @Service @Slf4j public class OrderService { @Resource private OrderMapper orderMapper; @Resource private OrderItemMapper orderItemMapper; @Resource private ProductMapper productMapper; //购买商品id private int purchaseProductId = 100100; //购买商品数量 private int purchaseProductNum = 1; @Autowired private PlatformTransactionManager platformTransactionManager; @Autowired private TransactionDefinition transactionDefinition; private Lock lock = new ReentrantLock(); // @Transactional(rollbackFor = Exception.class) public Integer createOrder() throws Exception{ Product product = null; lock.lock(); try { TransactionStatus transaction1 = platformTransactionManager.getTransaction(transactionDefinition); product = productMapper.selectByPrimaryKey(purchaseProductId); if (product==null){ platformTransactionManager.rollback(transaction1); throw new Exception("购买商品:"+purchaseProductId+"不存在"); } //商品当前库存 Integer currentCount = product.getCount(); System.out.println(Thread.currentThread().getName()+"库存数:"+currentCount); //校验库存 if (purchaseProductNum > currentCount){ platformTransactionManager.rollback(transaction1); throw new Exception("商品"+purchaseProductId+"仅剩"+currentCount+"件,无法购买"); } productMapper.updateProductCount(purchaseProductNum,"xxx",new Date(),product.getId()); platformTransactionManager.commit(transaction1); }finally { lock.unlock(); } TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition); Order order = new Order(); order.setOrderAmount(product.getPrice().multiply(new BigDecimal(purchaseProductNum))); order.setOrderStatus(1);//待处理 order.setReceiverName("xxx"); order.setReceiverMobile("13311112222"); order.setCreateTime(new Date()); order.setCreateUser("xxx"); order.setUpdateTime(new Date()); order.setUpdateUser("xxx"); orderMapper.insertSelective(order); OrderItem orderItem = new OrderItem(); orderItem.setOrderId(order.getId()); orderItem.setProductId(product.getId()); orderItem.setPurchasePrice(product.getPrice()); orderItem.setPurchaseNum(purchaseProductNum); orderItem.setCreateUser("xxx"); orderItem.setCreateTime(new Date()); orderItem.setUpdateTime(new Date()); orderItem.setUpdateUser("xxx"); orderItemMapper.insertSelective(orderItem); platformTransactionManager.commit(transaction); return order.getId(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理