JAVA全系列 教程
3762个小节阅读:7088.9k
目录
C语言快速入门
JAVA全系列 教程
面向对象的程序设计语言
Python全系列 教程
Python3.x版本,未来主流的版本
人工智能 教程
顺势而为,AI创新未来
大厂算法 教程
算法,程序员自我提升必经之路
C++ 教程
一门通用计算机编程语言
微服务 教程
目前业界流行的框架组合
web前端全系列 教程
通向WEB技术世界的钥匙
大数据全系列 教程
站在云端操控万千数据
AIGC全能工具班
A A
White Night
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。
- 取出记录时,获取当前 version
- 更新时,带上这个 version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
xxxxxxxxxx
<update id="decreaseStockForVersion" parameterType="int" >
UPDATE product SET count = count - #{count}, version = version + 1 WHERE id = #{id} AND count > 0 AND version = #{version}
</update>
xxxxxxxxxx
/**
* 创建订单 乐观锁
*
* @return
*/
@Transactional(rollbackFor = Exception.class)
@Override
public String createOrder(Integer productId, Integer count) throws Exception {
int retryCount = 0;
int update = 0;
// 1、根据商品id查询商品信息
Product product = productMapper.selectById(productId);
// 2、判断商品是否存在
if (product == null) {
throw new RuntimeException("购买商品不存在:" + productId + "不存在");
}
// 3、校验库存
if (count > product.getCount()) {
throw new Exception("库存不够");
}
// 乐观锁更新库存
// 更新失败,说明其他线程已经修改过数据,本次扣减库存失败,可以重试一定次数或者返回
// 最多重试3次
while(retryCount < 3 && update == 0){
update = this.reduceStock(product.getId(),count);
retryCount++;
}
if (update == 0){
throw new Exception("库存不够");
}
// 6、 创建订单
TOrder order = new TOrder();
order.setOrderStatus(1);//待处理
order.setReceiverName("张三");
order.setReceiverMobile("18587781068");
order.setOrderAmount(product.getPrice().multiply(new BigDecimal(count)));//订单价格
baseMapper.insert(order);
// 7、 创建订单和商品关系数据
OrderItem orderItem = new OrderItem();
orderItem.setOrderId(order.getId());
orderItem.setProduceId(product.getId());
orderItem.setPurchasePrice(product.getPrice());
orderItem.setPurchaseNum(count);
orderItemMapper.insert(orderItem);
return order.getId();
}
/**
* 减库存
* <p>
* 由于默认的事务隔离级别是可重复读,produce.findById()
* 得到的数据始终是相同的,所以需要提取reduceStock方法。每次循环都启动新的事务尝试扣减库存操作。
*/
@Transactional(rollbackFor = Exception.class)
public int reduceStock(int gid,int count) {
int result = 0;
//1、查询商品库存
Product product = productMapper.selectById(gid);
//2、判断库存是否充足
if (product.getCount() >= count) {
//3、减库存
// 乐观锁更新库存
result = productMapper.decreaseStockForVersion(gid,count, product.getVersion());
}
return result;
}
实时效果反馈
1.基于数据库如何实现乐观锁_______。
A for update
B 表加version字段
C synchronized
D 以上都是错误
2.乐观锁适用于__的应用类型,这样可以提高吞吐量。
A 多读
B 写多
C 删多
D 以上都是错误
答案
1=>B 2=>A