
Mysql Innodb 行级锁SELECT ....FOR UPDATE 需要配合事务一起使用
Thinkphp 举例
<?php
namespace Home\Controller;
class Test1Controller extends PublicController
{
public function testLock() {
$Model = D('Blog');
$Model->startTrans();
$lock = $Model->lock(true)->where('id=11')->find();
sleep(15);
$Model->commit();
dump($lock);
}
public function testLock3() {
$Model = D('Blog');
$Model->startTrans();
$lock1 = $Model->lock(true)->where('id=11')->find();
$Model->commit();
dump($lock1);
}
}
源码 PDO连库举例
<?php
$dsn = 'mysql:dbname=xxxx;host=123.56.154.xxx';
$user = 'root';
$password = '****';
try {
$pdo = new PDO($dsn, $user, $password);
$pdo->exec('SET NAMES UTF8');
// 捕获异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, 2);
} catch (PDOException $e) {
echo 'Error: ' . $e->getMessage();
}
try {
# 开启事务
$pdo->beginTransaction();
# 关闭自动提交
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
$sql = 'SELECT * FROM xmg_type2 WHERE id = 20 FOR UPDATE ';
$res1 = queryOne($sql);
sleep(15);
$pdo->commit();
echo time().'/';
print_r($res);
print_r($res1);
exit;
} catch (PDOException $e) {
# 回滚
echo 222;
$pdo->rollBack();
}
// 查询多条数据
function query($sql)
{
global $pdo;
$res = $pdo->prepare($sql);
$res->execute();
$data = $res->fetchAll(PDO::FETCH_ASSOC);
return $data;
}
// 查询一条数据
function queryOne($sql)
{
global $pdo;
$res = $pdo->prepare($sql);
$res->execute();
$data = $res->fetch(PDO::FETCH_ASSOC);
return $data;
}
// 执行sql
function exe($sql)
{
global $pdo;
$res = $pdo->exec($sql);
return $res;
}
// 上一次insert产生的id
function lastid()
{
global $pdo;
return $pdo->lastInsertId();
}
?>
Mysql 多种引擎均支持表锁 LOCK TABLES table1 FOR WRITE(READ)
使用该方式锁表时 不用配合 start transaction 开启事务,若使用start transaction 则会造成一个隐含的UNLOCK TABLES
被执行
<?php
$dsn = 'mysql:dbname=xxx;host=123.56.154.xxx';
$user = 'root';
$password = 'xxx';
try {
$pdo = new PDO($dsn, $user, $password);
$pdo->exec('SET NAMES UTF8');
// 捕获异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, 2);
} catch (PDOException $e) {
echo 'Error: ' . $e->getMessage();
}
try {
$sql = 'LOCK TABLE xmg_type1 WRITE';
//$sql = 'UNLOCK TABLES';
$res = exe($sql);
$sql = 'SELECT * FROM xmg_type1 ';
sleep(15);
$res1 = queryOne($sql);
echo time().'/';
print_r($res);
print_r($res1);
exit;
} catch (PDOException $e) {
# 回滚
echo 222;
$pdo->rollBack();
}
// 查询多条数据
function query($sql)
{
global $pdo;
$res = $pdo->prepare($sql);
$res->execute();
$data = $res->fetchAll(PDO::FETCH_ASSOC);
return $data;
}
// 查询一条数据
function queryOne($sql)
{
global $pdo;
$res = $pdo->prepare($sql);
$res->execute();
$data = $res->fetch(PDO::FETCH_ASSOC);
return $data;
}
// 执行sql
function exe($sql)
{
global $pdo;
$res = $pdo->exec($sql);
return $res;
}
// 上一次insert产生的id
function lastid()
{
global $pdo;
return $pdo->lastInsertId();
}
?>