首先介绍:唯一索引,防止插入重复数据
?当批量插入数据时,像我们这个表,lockName设置为唯一索引了——>当重复插入相同数据就会报错——>Duplicate entry ' ' for key '索引'?
insert into tb_name (field1,field2) values(f11,f12),(f21,f22)...
?ingore
当插入多条数据,重复数据会直接跳过
insert ignore into tb_name (field1,field2) values(f11,f12),(f21,f22)...
?Mysql乐观锁的实现
在表中加一个version列,当进行数据操作时,需要更新version字段值+1——>操作前提:读取到的version和数据库中的version相同才能更新否则cas
//1.查询数据的sql
select * from tb_item_stock where item_id=10001;
//2.修改数据的sql
update tb_item_stock set stock=stock+1,version=version+1 where item_id=10001 and version=1;
/**
* 模拟多版本号
*/
@Transactional
public void deduct2(){
//1.首先查询仓库里面的内容
List<Stock> stocks = this.stockMapper.queryStock("10001");
//获取第一条仓库记录
Stock stock = stocks.get(0);
//2.判断仓库是否充足
if(stock!=null&&stock.getStock()>0){
//2.1扣减库存,然后设置新的版本号进行更新
stock.setStock(stock.getStock()-1);
Integer version = stock.getVersion(); //获取当前商品版本
stock.setVersion(version+1); //更新一次版本加一次,如果中途有其他的更新操作就会失败
//2.2然后进行更新——>需要进行判断如果更新影响行数为0就进行cas操作
if(this.stockMapper.update(stock,new UpdateWrapper<Stock>()
.eq("item_id",stock.getItemId())
.eq("version",version))==0){
this.deduct2();//cas
}
}
?(36条消息) 随笔感悟:Mysql悲观锁和乐观锁_Fairy要carry的博客-CSDN博客
Mysql分布式锁的实现
我们这里就是创建一张锁表,通过表中的数据——>实现加锁和解锁,当需要锁住某个资源的时候我们就向表中插入一条记录,lockName设置为唯一index(加锁)——>好处:保证了插入的唯一性
?解锁:我们直接利用id进行判断删除
/**
* 1.数据库锁测试
*/
public void deduct(){
//0.加锁
Lock lock = new Lock();
lock.setLockName("lock");
this.lockMapper.insert(lock);
//1.业务处理
System.out.println("拿到锁资源...");
//2.解锁,根据锁的标识去删除
this.lockMapper.deleteById(lock.getId());
}
死锁的处理和可重入锁的处理——>在表中设计好了,超时时间就释放,线程id,服务id,可重入次数等
|