用Java实现MySQL分布式锁

一.前期准备工作

  1. 我们需要连接MySQL数据库,我们需要连接数据库的jar包和数据源,这里我用的是c3p0数据源。
  2. 持久层我们使用mybatis框架。
  3. 我们在spring配置文件里配置好数据源以及mybatis相关的配置。
 <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
        <property name="initialSize" value="30"></property>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sessionFactoryBean"></property>
        <!--配置mapper接口的具体位置-->
        <property name="basePackage" value="demo"></property>
    </bean>

    <!--配置sessionFactoryBean,-->
    <bean id="sessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--配置mapper.xml的具体位置-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <property name="mapperLocations" value="demo/*.xml"></property>
        <property name="dataSource" ref="dataSource"></property>
    </bean>
  1. 数据库里面建好相应的锁表,表的信息如下
    在这里插入图片描述

二.代码编写阶段

我们模仿创建订单的场景,编写对应的OrderMapper.xml

	<insert id="insertOrder" parameterType="Integer">
        update method_lock set method_name='createOrder' where id=#{id}
    </insert>
	
	**注意此处的 for update 是锁住表的关键**
    <select id="queryLock" parameterType="Integer" resultType="String">
        select method_name from method_lock where id=#{id} for update
    </select>

    <delete id="deleteLock" parameterType="Integer">
        update method_lock set method_name='' where id =#{id}
    </delete>

    <update id="incLockCount" parameterType="Integer">
        update lock_count set lockcount=lockcount+1 where id=#{id}
    </update>

对应的OrderMapper接口

	void insertOrder(@Param("id") Integer id);

    void deleteLock(@Param("id") Integer id);

    String queryLock(@Param("id") Integer id);

创建对应的消费者ConsumerService,lock方法是消费者去获取锁,delete方法是消费者去删除使用过的锁

	@Transactional
    public boolean lock(){
        String method_name=orderMapper.queryLock(1);
        if(method_name==null||"".equals(method_name)){
            orderMapper.insertOrder(1);
            return true;
        }
        return false;
    }

    @Transactional
    public void deleteLock(){
        orderMapper.deleteLock(1);
    }

创建对应的消费者Consumer去创建订单

public void createOrder(){
        long endtime = System.currentTimeMillis()+3000;
        while(System.currentTimeMillis()<endtime){
            if(consumerService.lock()){
            	//这里可以写你想要做的事。
                consumerService.deleteLock();
                break;
            }
            //如果没有获取到锁,等待100毫秒再去获取
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

测试阶段,创建100个消费者同时去创建订单

public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:spring-config.xml");
        for(int i=0;i<100;i++){
            new Thread(new Consumer("consumer:"+i)).start();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值