溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

mysql如何實(shí)現(xiàn)分布式鎖

發(fā)布時(shí)間:2021-07-07 16:56:22 來(lái)源:億速云 閱讀:400 作者:chen 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“mysql如何實(shí)現(xiàn)分布式鎖”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“mysql如何實(shí)現(xiàn)分布式鎖”吧!

一、具體實(shí)現(xiàn)

1、共享資源類TicketResource

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() + "賣(mài)了1張票,火車票還剩:" + (--ticket) + "張";
		}
		else {
			res = "火車票售罄!";
		}
		
		System.out.println(res);
		
		return res;
	}
}

2、表對(duì)象實(shí)體LockPo

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;
}

3、dao

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); //寫(xiě)
    
    public int del(Long id); //寫(xiě)
}

4、controller

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();
	}
  }
}

5、application.yml

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

6、LockMapper.xml

<?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>

7、sql

CREATE TABLE `t_lock` (
   `id` BIGINT(11) COMMENT 'ID',
   PRIMARY KEY (`id`)
 ) ENGINE=INNODB DEFAULT CHARSET=utf8

8、數(shù)據(jù)表記錄

mysql如何實(shí)現(xiàn)分布式鎖

9、鎖相關(guān)類

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,再次調(diào)用此方法會(huì)拋出異常,返回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();
		}
	}

}

10、輸出

分布式鎖-線程:qtp879353005-178賣(mài)了1張票,火車票還剩:19張
分布式鎖-線程:qtp879353005-175賣(mài)了1張票,火車票還剩:18張
分布式鎖-線程:qtp879353005-177賣(mài)了1張票,火車票還剩:17張
分布式鎖-線程:qtp879353005-180賣(mài)了1張票,火車票還剩:16張
分布式鎖-線程:qtp879353005-179賣(mài)了1張票,火車票還剩:15張
分布式鎖-線程:qtp879353005-177賣(mài)了1張票,火車票還剩:14張
分布式鎖-線程:qtp879353005-180賣(mài)了1張票,火車票還剩:13張
分布式鎖-線程:qtp879353005-179賣(mài)了1張票,火車票還剩:12張
分布式鎖-線程:qtp879353005-177賣(mài)了1張票,火車票還剩:11張
分布式鎖-線程:qtp879353005-180賣(mài)了1張票,火車票還剩:10張
分布式鎖-線程:qtp879353005-177賣(mài)了1張票,火車票還剩:9張
分布式鎖-線程:qtp879353005-180賣(mài)了1張票,火車票還剩:8張
分布式鎖-線程:qtp879353005-179賣(mài)了1張票,火車票還剩:7張
分布式鎖-線程:qtp879353005-177賣(mài)了1張票,火車票還剩:6張
分布式鎖-線程:qtp879353005-179賣(mài)了1張票,火車票還剩:5張
分布式鎖-線程:qtp879353005-177賣(mài)了1張票,火車票還剩:4張
分布式鎖-線程:qtp879353005-180賣(mài)了1張票,火車票還剩:3張
分布式鎖-線程:qtp879353005-179賣(mài)了1張票,火車票還剩:2張
分布式鎖-線程:qtp879353005-177賣(mài)了1張票,火車票還剩:1張
分布式鎖-線程:qtp879353005-180賣(mài)了1張票,火車票還剩:0張

二、mysql實(shí)現(xiàn)分布式鎖的優(yōu)缺點(diǎn)

缺點(diǎn):

① 性能低下(頻繁磁盤(pán)io)

② 產(chǎn)生死鎖概率高

③ 不太適合太高并發(fā)場(chǎng)景

④ waitLock()方法頻繁地輪詢不優(yōu)雅

到此,相信大家對(duì)“mysql如何實(shí)現(xiàn)分布式鎖”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI