mysql实现分布式锁_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > mysql实现分布式锁

mysql实现分布式锁

 2019/5/10 18:52:23  我的无奈  程序员俱乐部  我要评论(0)
  • 摘要:1、最近再学分布式锁,把自己所学的一点心得分享给大家2、首先介绍我的springboot项目结构数据库表的结构很简单,t_lock表就一个主键字段id3、实现锁的代码这里运用了模板设计模式锁接口:publicinterfaceTestLock{/***加锁*/publicvoidgetLock();/***解锁*/publicvoidunLock();}锁的抽象实现类:publicabstractclassAbstractTestLockimplementsTestLock
  • 标签:实现 SQL MySQL

1、最近再学分布式锁,把自己所学的一点心得分享给大家
2、首先介绍我的spring boot项目结构

?数据库表的结构很简单,t_lock表就一个主键字段id



?3、实现锁的代码

这里运用了模板设计模式

接口

public interface TestLock {

?

/**

* 加锁

*/

public void getLock();

/**

* 解锁

*/

public void unLock();

?

}

锁的抽象实现类:

public abstract class AbstractTestLock implements TestLock{

?

@Override

public void getLock() {

/**

* 1、竞争锁

* 2、占有锁

* 3、任务阻塞

* 4、释放锁

*/

if(tryLock()) {

System.out.println("========获取锁的资源===========");

}else {

//等待

waitLock();

//重新获取资源

getLock();

}

}

public abstract void waitLock();

public abstract boolean tryLock();

}

?锁的实现:

@Service

public class MySqlLock extends AbstractTestLock{

?

@Resource

private LockMapper lockMapper;

?

private static final Integer ID = 1;

?

@Override

public boolean tryLock() {

try {

Lock lock = new Lock();

lock.setId(ID);

lockMapper.save(lock);

}catch (Exception e) {

return false;

}

return true;

}

?

@Override

public void unLock() {

lockMapper.delete(ID);

}

?

@Override

public void waitLock() {

try {

Thread.currentThread().sleep(10);

}catch (Exception e) {

e.printStackTrace();

}

}

?

}

仿照订单生成:

public class OrderGenerator {

// 全局订单号

public static int num = 0;

?

public String getNumber() {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

return sdf.format(new Date())+"-"+ ++num;

}

}

?

4、测试

public class MysqlLockTest extends LockApplicationTests{

?

public OrderGenerator generator = new OrderGenerator();

?

@Resource

private TestLock lock;

?

@Test

public void testGetOrderNum() throws InterruptedException {

System.out.println("=======生成唯一订单号==========");

for(int i=0; i< 50 ; i++) {

new Thread(

(Runnable) () -> { getNumber(); }

).start();

}

Thread.currentThread().join();

}

?

private void getNumber() {

try {

lock.getLock();

String number = generator.getNumber();

System.out.println(Thread.currentThread().getName() + ",生成订单ID:"+ number);

}catch (Exception e) {

e.printStackTrace();

}finally {

lock.unLock();

}

}

?

}

?

测试结果:



?可以看见总共生成了50个订单号,没有重复出现同样的订单号,这样子就实现了用mysql实现分布式锁。

?

5、使用mysql实现分布式锁的弊端:

? ? a、性能差,无法适应高并发场景,众所周知,mysql的并发瓶颈在300-700之间,当然也有可能达不到,所以一旦并发超过700的话,那么mysql就没法应用于此场景;

? ? b、容易死锁,一旦数据库中数据一开始有数据,那么就会一直处于死锁状态,或者删除数据失败,那么也会一直处于死锁;

? ? c、无法优雅的实现阻塞式锁。

?

发表评论
用户名: 匿名