我是靠谱客的博主 英俊秀发,最近开发中收集的这篇文章主要介绍thinkphp3 数据库锁的使用与研究,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近项目涉及到了一个有可能出现并发的功能,因此网上查询了一下有关于tp3表锁的知识,可惜都不是非常详细,因此决定自己来进行一次测试。

 

情况一:两进程查询同一条记录,不加锁

 public function testLock()
    {
        $uuid = I('uuid');
        $result = M('purchase_detail', 'iwh_')->where(['uuid' => $uuid])->find();//根据uuid查找某条记录
        sleep(10);//休眠10秒
        $this->successAjaxReturn("运行结束");//返回结果

    }

用python模拟查询,最后得出结果:两个进程均运行10秒,互不干扰。

情况二:两进程查询同一条记录,加锁

 public function testLock()
    {
        $uuid = I('uuid');
        $result = M('purchase_detail', 'iwh_')
            ->lock(true)->where(['uuid' => $uuid])
            ->find();//根据uuid查找某条记录
        sleep(10);//休眠10秒
        $this->successAjaxReturn("运行结束");//返回结果

    }

结果:依旧互不干扰

情况三:两进程查询同一条记录,加锁,停留10秒,随后对该记录进行修改,进程1,将记录修改为test1,进程2将备注字段修改为test2。

​

 public function testLock()
    {
        $uuid = I('uuid');
        $result = M('purchase_detail', 'iwh_')
            ->lock(true)->where(['uuid' => $uuid])
            ->find();//根据uuid查找某条记录
        sleep(10);//休眠10秒
        $this->successAjaxReturn("运行结束");//返回结果

    }

结果:互不干扰,备注最终变为test2

情况4:两个进程在事务下查询同一个记录

 public function testLock1()
    {
        $uuid = I('uuid');//uuid
        $model = new Model();
        $model->startTrans();
        $result = M('purchase_detail', 'iwh_')->lock(true)->where(['remark' => $uuid])->find();
        sleep(10);
        $model->commit();
        $this->successAjaxReturn("运行结束");

    }

结果:进程1执行了10秒,进程2执行了20秒,说明进程2在等待进程1的执行。

从以上结果我们可以推断出,加锁语句必须放在事务中才能起作用。

 

情况5:两个进程在事务下查询不同记录

结果同上,说明出现了锁表的情况,而非锁行。

这个时候突然想到,我用的引擎是默认MyISAM引擎,好像不支持锁行?

更换一下试试。

打开配置文件my.ini,将"default-storage-engine=MYISAM"修改为"default-storage-engine=innodb"

查看一下,确认有修改成功

测试结果:在查询不同行的情况下,依旧发生了阻塞。

好吧,tp3行级锁究竟应该怎么用呢?用原生语句试试!

  public function testLock1()
    {
        $uuid = I('uuid');//uuid
        M('purchase_detail','iwh_')->startTrans();
//        $result = M('purchase_detail', 'iwh_')->lock(true)->where(['remark' => $uuid])->find();
        $sql = sprintf("select * from iwh_purchase_detail where  uuid = '%s' for update ",$uuid);//查询语句
        M()->execute($sql);
        sleep(10);
        M('purchase_detail','iwh_')->commit();
        $this->successAjaxReturn("运行结束");

    }

 

测试结果:成功触发行级锁!在查询不同行时,没有相互堵塞。在查询同一行时,代码发生了堵塞的情况!

总结:

1、 要想触发mysql的锁机制,必须将触发语句放入到事务处理之中。

2、tp3的框架语句只能触发表级锁,而无法触发行级锁。

2、要想触发mysql的行级锁,必须用执行原生语句的方式,并且要将数据库引擎换成innodb

最后

以上就是英俊秀发为你收集整理的thinkphp3 数据库锁的使用与研究的全部内容,希望文章能够帮你解决thinkphp3 数据库锁的使用与研究所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部