伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

数据库悲观锁 for update 的使用场景之一:分布式锁

来源:本站原创 浏览:95次 时间:2022-05-11

锁不管是在工作中还是生活中都到处存在。在编程的世界中,也是普遍的存在,用不好,会产生很多麻烦问题。

前两天有一个网友在群里问我 synchronized 锁的问题,当时没怎么细说,以后有时间了来写篇文章。本文主要是介绍借用数据库的悲观锁来实现一个分布式的锁。

分布式锁的实现有很多种方法,后面我还会写几篇用 Redis、Zookeeper 等来实现分布式锁。

目前几乎所有的大型网站和应用都采用的是分布式架构。在分布式环境中 CAP 理论至关重要,不懂 CAP 理论的可以查看我前面的文章《详解 CAP 定理 Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)》。

分布式锁顾名思义是发生在分布式环境中的。对于单进程场景,我们可以使用语言和类库提供的锁,对于分布式锁,我也可以使用分布式锁。也就是说同样的锁使用的环境不同,分布式环境中用的锁就叫分布式锁!

根据上面的理解,分布式锁是不是应该具备下面的特点:

  1. 分布式锁必须保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行;

  2. 一个线程获得了锁,其他线程必须等待持有锁的线程释放掉才能再获取;

  3. 锁必须要有超时机制(避免死锁)

基于上面的特点,我们就可以通过数据库的悲观锁来实现一个分布式锁。

代码非常的简单,使用 for update 即可。具体如下:

public class XttblogLock {   private DataSource dataSource;   private static final String cmd = "select * from xttblog_lock where id = 1 for update";   public XttblogLock(DataSource ds) {       this.dataSource = ds;   }   public static interface CallBack{       public void doAction();   }   public void lock(CallBack callBack)  {       Connection conn = null;       PreparedStatement stmt = null;       ResultSet rs = null;       try {           //try get lock           System.out.println(Thread.currentThread().getName() + " begin try lock");           conn = dataSource.getConnection();           conn.setAutoCommit(false);           stmt = conn.prepareStatement(cmd);           rs = stmt.executeQuery();           //do business thing           callBack.doAction();           //release lock           conn.commit();           System.out.println(Thread.currentThread().getName() + " release lock");       } catch (SQLException e) {           e.printStackTrace();       } finally {           if (null != conn) {               try {                   conn.close();               } catch (SQLException e) {                   e.printStackTrace();               }           }       }   }}

该锁的调用也非常的简单,具体代码如下:使用数据库悲观锁实现分布式锁主要用了数据库的 for update 命令,执行改命令后,对应行记录会被锁住,其它线程会被阻塞主,直到获取到这行记录的线程提交了事务。这里需要注意要把自动提交设置为 false。

该锁的调用也非常的简单,具体代码如下:

final XttblogLock xttblogLock = new XttblogLock(dataSource);xttblogLock.lock(new CallBack() {   @Override   public void doAction() {       System.out.println(Thread.currentThread().getName() + "beging do somthing");       try {           System.out.println("业余草:www.xttblog.com 欢迎你!");           Thread.sleep(2000);       } catch (InterruptedException e) {           e.printStackTrace();       }       System.out.println(Thread.currentThread().getName() + "end do somthing");   }});

虽然数据库的 for update 悲观锁可以用来做分布式锁,但实际的生产过程中采用这种方法的非常少,因为它性能不是很高。

图片虽然数据库的 for update 悲观锁可以用来做分布式锁,但实际的生产过程中采用这种方法的非常少,因为它性能不是很高。

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763,QQ2群:454796847,QQ3群:187424846。QQ群进群密码:xttblog,想加微信群的朋友,可以微信搜索:xmtxtt,备注:“xttblog”,添加助理微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net