分布式锁(1) ----- 介绍和基于数据库的分布式锁
Posted wuweishuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式锁(1) ----- 介绍和基于数据库的分布式锁相关的知识,希望对你有一定的参考价值。
线程锁与分布式锁
1.java的synchronize和Lock都是属于线程锁,只能保证同一个进程内的多线程对共享变量修改访问同步。它们的原理都是设置一个可以让所有线程访问到标记,如synchronize是设置对象头的Mark Word,而Lock类是基于AQS的volatile修饰的state。
2.分布式锁是属于进程范畴的,而且进程可以在不同的机器上。它要保证的是多个进程对共享变量修改访问同步(例如集群环境下同时修改缓存和数据库)。分布式锁也同样需要一个可以让所有进程访问到的标记(如数据库的字段,redis的数据,zookeeper的节点等)来控制同步。
实现方法
1.基于数据库的分布式锁
2.基于redis的分布式锁
3.基于zookeeper的分布式锁
基于数据库的分布式锁
基于表主键唯一
利用主键具有唯一性的性质,加锁时向数据库插入以锁名为主键的数据,解锁时删除该数据。
优化:
1.没有过期时间,如果获得锁的服务解锁失败,将导致其他服务无法获得锁。网上也有解决方法:增加过期时间字段,定期清除过期锁数据。
2.重入性,增加获得锁服务的标记字段。
基于版本号字段
为表结构增加版本号字段,每次获取数据将版本号获取到,下次修改数据时判断当前版本是否该版本号。思路是与mysql的mvcc机制差不多的。
基于排他锁
public boolean lock(){
connection.setAutoCommit(false)
while(true){
try{
result = select * from lock where lockName=xxx for update;
if(result==null){
return true;
}
}catch(Exception e){
}
sleep(1000);
}
return false;
}
public void unlock(){
connection.commit();
}
1.该方法是基于mysql的innodb的行级锁,所以lockName字段必须有索引存在,但因此也有一个问题,是否使用索引是有mysql来判断的,如果mysql认为全表查询更快,会使用表锁,那将会影响lock表的所有分布式锁。
2.for update会在执行失败是一直阻塞到成功。
优缺点
优点:容易实现理解
缺点:占用数据库连接,性能较低。
参考资料
https://www.cnblogs.com/seesun2012/p/9214653.html
以上是关于分布式锁(1) ----- 介绍和基于数据库的分布式锁的主要内容,如果未能解决你的问题,请参考以下文章