分布式锁-mysql行锁

分布式锁-mysql行锁

锁工具类 MutexUtil

public class MutexUtil {

    public static void lock(String mutexName,Connection connection)  {
        PreparedStatement preparedStatement= null;//获得锁
        ResultSet resultSet = null;
        int id=-1;
        try {
            //不自动提交事物
            connection.setAutoCommit(false);
            //获取行级锁
            preparedStatement = connection.prepareStatement
                    ("select id, mutex_name  from mutex  where mutex_name = ? for update ");
            preparedStatement.setString(1,mutexName);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next())
                id=resultSet.getInt(1);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println("获得锁 id="+id);

    }
    public static void unlock(Connection connection){//关闭锁
        try {
            //关闭锁 同时提交事物
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

测试类

@Autowired
 DataSource dataSource;
void testMapper() throws SQLException {
    Connection connection=dataSource.getConnection();
    Connection connection2=dataSource.getConnection();
    MutexUtil.lock("mutex1",connection);

    Runnable run=new Runnable() {
        @Override
        public void run() {
            MutexUtil.lock("mutex1",connection2);
            MutexUtil.unlock(connection2);
        }
    };
    //开启其他线程索取锁
    Thread thread=new Thread(run);
    thread.start();
    for(int i=0;i<100000;i++){
        System.out.print(i+" ");
    }
    //while (true);
   MutexUtil.unlock(connection);
}

输出

获得锁 id=1
1 2 ... 100000
获得锁 id=1

证明必须要等第一个线程释放锁后,第二个线程才能获取锁

优点:
实现简单

缺点:
1.这把锁没有失效时间,一旦出错,会无法释放锁,其他线程无法再获得到锁
而且排他锁长时间不提交,就会占用数据库连接。一旦类似的连接变得多了,就可能把数据库连接池撑爆
2.锁定之后服务宕机,无法释放?使用这种方式,服务宕机之后数据库会自己把锁释放掉

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值