点网站出图片怎么做,深圳市中心在哪,站内关键词排名优化软件,海南通信建设有限公司官方网站文章目录 使用数据锁#xff1a;悲观锁 或者 乐观锁悲观锁乐观锁mysql锁总结 使用数据锁#xff1a;悲观锁 或者 乐观锁 一个sql#xff1a;直接更新时判断#xff0c;在更新中判断库存是否大于0 update table set surplus (surplus - buyQuantity) where id 1 and (surp… 文章目录 使用数据锁悲观锁 或者 乐观锁悲观锁乐观锁mysql锁总结 使用数据锁悲观锁 或者 乐观锁 一个sql直接更新时判断在更新中判断库存是否大于0 update table set surplus (surplus - buyQuantity) where id 1 and (surplus - buyQuantity) 0 ; 悲观锁在读取数据时锁住那几行其他对这几行的更新需要等到悲观锁结束时才能继续 。 select … for update 乐观锁读取数据时不锁更新时检查是否数据已经被更新过如果是则取消当前更新进行重试。 version 或者 时间戳CAS思想。
悲观锁 在MySQL的InnoDB中预设的Tansaction isolation level 为REPEATABLE READ可重读 在SELECT 的读取锁定主要分为两种方式 SELECT … LOCK IN SHARE MODE 共享锁SELECT … FOR UPDATE 悲观锁这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时都必须等待其它事务数据被提交(Commit)后才会执行。而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同一个表单时很容易造成死锁。简单的说如果SELECT 后面若要UPDATE 同一个表单最好使用SELECT … FOR UPDATE。 代码实现
改造StockService 在StockeMapper中定义selectStockForUpdate方法
public interface StockMapper extends BaseMapperStock {public Stock selectStockForUpdate(Long id);
}在StockMapper.xml中定义对应的配置
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.atguigu.distributedlock.mapper.StockMapperselect idselectStockForUpdate resultTypecom.atguigu.distributedlock.pojo.Stockselect * from db_stock where id #{id} for update/select
/mapper压力测试
注意测试之前需要把库存量改成5000。压测数据如下比jvm性能高很多比无锁要低将近1倍
mysql数据库存 乐观锁
乐观锁 Optimistic Locking 相对悲观锁而言乐观锁假设认为数据一般情况下不会造成冲突所以在数据进行提交更新的时候才会正式对数据的冲突与否进行检测如果发现冲突了则重试。那么我们如何实现乐观锁呢
使用数据版本Version记录机制实现这是乐观锁最常用的实现 方式。一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时将version字段的值一同读出数据每更新一次对此version值加一。当我们提交更新的时候判断数据库表对应记录 的当前版本信息与第一次取出来的version值进行比对如果数据库表当前版本号与第一次取出来的version值相等则予以更新。
给db_stock表添加version字段 对应也需要给Stock实体类添加version属性。此处略。。。。
代码实现
public void checkAndLock() {// 先查询库存是否充足Stock stock this.stockMapper.selectById(1L);// 再减库存if (stock ! null stock.getCount() 0){// 获取版本号Long version stock.getVersion();stock.setCount(stock.getCount() - 1);// 每次更新 版本号 1stock.setVersion(stock.getVersion() 1);// 更新之前先判断是否是之前查询的那个版本如果不是重试if (this.stockMapper.update(stock, new UpdateWrapperStock().eq(id, stock.getId()).eq(version, version)) 0) {checkAndLock();}}
}重启后使用jmeter压力测试工具结果如下 修改测试参数如下 测试结果如下 说明乐观锁在并发量越大的情况下性能越低因为需要大量的重试并发量越小性能越高。
mysql锁总结
性能一个sql 悲观锁 jvm锁 乐观锁
如果追求极致性能、业务场景简单并且不需要记录数据前后变化的情况下。
优先选择一个sql
如果写并发量较低多读争抢不是很激烈的情况下优先选择乐观锁
如果写并发量较高一般会经常冲突此时选择乐观锁的话会导致业务代码不间断的重试。
优先选择mysql悲观锁
不推荐jvm本地锁。