本篇内容主要讲解“mysql如何实现分布式锁”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql如何实现分布式锁”吧!
package com.lau.mysql.resource;
import org.springframework.stereotype.Component;
/**
* @ClassName: TicketResource
* @Description: TODO
* @author Liu
* @date 2021年4月18日 下午3:57:38
*/
@Component
public class TicketResource {
private Integer ticket = 20;
public String use(){
String res = null;
if(this.ticket > 0) {
res = "分布式锁-线程:" + Thread.currentThread().getName() + "卖了1张票,火车票还剩:" + (--ticket) + "张";
}
else {
res = "火车票售罄!";
}
System.out.println(res);
return res;
}
}
package com.lau.mysql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LockPo implements Serializable {
private Long id;
}
package com.lau.mysql.dao;
import org.apache.ibatis.annotations.Mapper;
import com.lau.mysql.entity.LockPo;
@Mapper
public interface LockDao {
public int create(Long id); //写
public int del(Long id); //写
}
package com.lau.mysql.controller;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.lau.mysql.lock.Lock;
import com.lau.mysql.resource.TicketResource;
@RestController
public class LockController {
@Resource
private Lock lock;
@Resource
private TicketResource ticketResource;
@GetMapping(value = "/mysql/distributed/lock")
public String purchaseTicket(){
try {
lock.getLock();
return ticketResource.use();
} finally {
lock.unLock();
}
}
}
server:
port: 8001
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: ******
druid:
validationQuery: SELECT 1
mybatis:
mapperLocations: classpath:mapper/*.xml
type-aliases-package: com.lau.mysql.entity
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lau.mysql.dao.LockDao">
<resultMap id="BaseResultMap" type="com.lau.mysql.entity.LockPo">
<id column="id" property="id" jdbcType="BIGINT"/>
</resultMap>
<insert id="create" parameterType="java.lang.Long">
insert into t_lock(id) values(#{id});
</insert>
<insert id="del" parameterType="java.lang.Long">
delete from t_lock where id = #{id};
</insert>
</mapper>
CREATE TABLE `t_lock` (
`id` BIGINT(11) COMMENT 'ID',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
package com.lau.mysql.lock;
/**
* @ClassName: Lock
* @Description: TODO
* @author Liu
* @date 2021年4月18日 下午3:32:23
*/
public interface Lock {
void getLock();
void unLock();
}
package com.lau.mysql.lock;
/**
* @ClassName: LockManager
* @Description: 本类采用了模板方法模式
* @author Liu
* @date 2021年4月18日 下午3:30:21
*/
public abstract class AbstractLock implements Lock{
@Override
public void getLock() {
if(this.tryLock()) {
}
else {
this.waitLock();
this.getLock();
}
}
public abstract Boolean tryLock();
public abstract void waitLock();
}
package com.lau.mysql.lock.impl;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.lau.mysql.dao.LockDao;
import com.lau.mysql.lock.AbstractLock;
/**
* @ClassName: LockImpl
* @Description: TODO
* @author Liu
* @date 2021年4月18日 下午3:46:34
*/
@Component
public class LockImpl extends AbstractLock{
@Autowired
private LockDao lockDao;
@Override
public void unLock() {
lockDao.del(1L);
}
/**
* 注意如果已存在主键id 1,再次调用此方法会抛出异常,返回false(锁互斥)
*/
@Override
public Boolean tryLock() {
try {
int create = lockDao.create(1L);
return create > 0;
}
catch (Exception e) {
return false;
}
}
@Override
public void waitLock() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
分布式锁-线程:qtp879353005-178卖了1张票,火车票还剩:19张 分布式锁-线程:qtp879353005-175卖了1张票,火车票还剩:18张 分布式锁-线程:qtp879353005-177卖了1张票,火车票还剩:17张 分布式锁-线程:qtp879353005-180卖了1张票,火车票还剩:16张 分布式锁-线程:qtp879353005-179卖了1张票,火车票还剩:15张 分布式锁-线程:qtp879353005-177卖了1张票,火车票还剩:14张 分布式锁-线程:qtp879353005-180卖了1张票,火车票还剩:13张 分布式锁-线程:qtp879353005-179卖了1张票,火车票还剩:12张 分布式锁-线程:qtp879353005-177卖了1张票,火车票还剩:11张 分布式锁-线程:qtp879353005-180卖了1张票,火车票还剩:10张 分布式锁-线程:qtp879353005-177卖了1张票,火车票还剩:9张 分布式锁-线程:qtp879353005-180卖了1张票,火车票还剩:8张 分布式锁-线程:qtp879353005-179卖了1张票,火车票还剩:7张 分布式锁-线程:qtp879353005-177卖了1张票,火车票还剩:6张 分布式锁-线程:qtp879353005-179卖了1张票,火车票还剩:5张 分布式锁-线程:qtp879353005-177卖了1张票,火车票还剩:4张 分布式锁-线程:qtp879353005-180卖了1张票,火车票还剩:3张 分布式锁-线程:qtp879353005-179卖了1张票,火车票还剩:2张 分布式锁-线程:qtp879353005-177卖了1张票,火车票还剩:1张 分布式锁-线程:qtp879353005-180卖了1张票,火车票还剩:0张
缺点:
① 性能低下(频繁磁盘io)
② 产生死锁概率高
③ 不太适合太高并发场景
④ waitLock()方法频繁地轮询不优雅
到此,相信大家对“mysql如何实现分布式锁”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云数据库 MySQL」免部署即开即用,比自行安装部署数据库高出1倍以上的性能,双节点冗余防止单节点故障,数据自动定期备份随时恢复。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/Howard2016/blog/5023235