当前位置:编程学习 > thinkphp >>

thinkphp事务行锁代码 模型和db

thinkphp lock 行锁 的使用和例子

在开发需求中会遇到这样一种情况,并发请求。数据库的更新还没执行结束,另一个select查出的数据,会是更新之前的数据,那就会造成查询数据不准确。
那怎么解决呢?用innoDB的事务和锁就能解决这个问题。在我们当前行更新还没结束的时候,select查询此行的数据会被锁起来。

比如我们数据库有这样两行数据

id,num

1,700

2,2


我们把id=1的num数据更新为1000,sleep10秒,这时候我们select id=1的数据时,会等待update的更新结束,如果我们select id=2的时候,不需要等待10秒,会立马获取到数据。
这就是InnoDB的行锁,只会锁当前update的那行数据,不会锁整表。
下面会列出测试代码,记得吧引擎改为innoDB,不是MYISAM。

class Index extends Controller
{
    public function index()
    {
        $model=Db::name('test');
        $model->startTrans();
        try{
            $list=$model->lock(true)->where(['id'=>1])->find();
            $model->where(['id'=>1])->data(['num'=>900])->update();//id为1的更新
            sleep(10);//等待10秒
            $model->commit();
            print_r($list);
        }catch (\Exception $exception){
            $model->rollback();
            throw $exception;
        }
    }
 
 
    public function index2(){
        $model=Db::name('test');
        $model->startTrans();
        try{
            $list=$model->lock(true)->where(['id'=>1])->find();//id为1在更新时,select id=1 会等待。把ID改为2时,不等待
            $model->commit();
            print_r($list);
        }catch (\Exception $exception){
            $model->rollback();
            throw $exception;
        }
    }
}
 
我们把id=1的num数据更新为1000,sleep10秒,这时候我们select id=1的数据时,会等待update的更新结束,如果我们select id=2的时候,不需要等待10秒,会立马获取到数据。
这就是InnoDB的行锁,只会锁当前update的那行数据,不会锁整表。
下面会列出测试代码,记得吧引擎改为innoDB,不是MYISAM。

public function debug()
    {
        Db::startTrans();
        $res1 = Db::name('num') -> where(['id'=>1]) -> lock(true)-> find();
        sleep(10);
        $res2 = Db::name('num') -> where(['id'=>1]) -> update(['num'=>999]);
        Db::commit();
        dump($res2);
    }

    public function debug2()
    {
        $res2 = Db::name('num') -> where(['id'=>1]) -> update(['num'=>888]);
        dump($res2);
    }

测试步骤:请求index后,在请求index2,就会看到index2会等index加载结束,我们才能看到index2的打印结果。如果index2的id改为2后,则不会受到index的影响
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,