YiluPHP
这家伙很懒,什么都没有留下...

经验 MYSQL锁表锁行测试及Laravel中锁表锁行的用法

浏览数 222211
#锁住 test_article 表
LOCK TABLE test_article READ;

#在其它客户端或网页中查询该表内容将等待

#解锁所有表
UNLOCK TABLES;

#查看 InnerDB 中当前锁和历史锁状态
show status like 'innodb_row_lock%';

#查看历史锁表次数和历史锁等待次数
show status like 'table%';

#设置不自动解锁,此值默认为1,表示运行完select语句后马上就解锁了
set autocommit=0;
#开启一个行级排他锁
SELECT * FROM test_article WHERE article_id=4 FOR UPDATE;

#在其它客户端或网页中查询该行内容将等待

#提交后解锁
COMMIT;

#开启一个行级共享锁
SELECT * FROM test_article WHERE article_id=4 LOCK IN SHARE MODE;

UPDATE test_article SET title="4444" WHERE cat_id=4;

#查看当前MySQL的进程
show PROCESSLIST;


在 Laravel 中锁行测试:
//设置不自动解锁,此值默认为1,表示运行完select语句后马上就解锁了
\DB::statement('set autocommit=0');
//锁行
 $res = \DB::table('test_article')->where('article_id',4)->lockForUpdate()->get();

//更新行
$affected = \DB::update('update test_article set title=? where article_id = ?', ['反腐进展'.date('H:i:s'), 4]);

//解锁行
\DB::statement('commit');

在 Laravel 中执行以下代码锁表时报错,还不知道为什么不能这样操作
\DB::statement('LOCK TABLE test_article READ');
\DB::statement('unlock tables');

报下面的错误:
Whoops, looks like something went wrong.

QueryException in Connection.php line 647: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. (SQL: LOCK TABLE test_article READ)

不使用Laravel框架,纯PHP使用PDO连接数据库是可以执行锁表命令的
$pdo = new \PDO("mysql:host=127.0.0.1;dbname=dbname", 'yourname', 'yourpassword'); //创建一个pdo对象
$pdo->exec("set names 'utf8'");
$pdo->exec("LOCK TABLE test_article READ");
sleep(10);
$pdo->exec("UNLOCK TABLES");
sleep(8);

我来说说