private function getDb()
{
return new \Workerman\MySQL\Connection('DB_HOST', 'DB_PORT', 'DB_USER', 'DB_PWD', 'DB_NAME');
}
public function func($id)
{
$db = $this->getDb();
try {
// 一些業(yè)務
// 更新操作
$db->query("UPDATE `table_name` SET field1 = 1 WHERE `id` = {$id}");
// result通過業(yè)務拿到
if ($result) {
$db->query("UPDATE `table_name` SET field2 = 2 WHERE `id` = {$id}");
}
} catch (\Exception $exception) {
echo $exception->getMessage();
}
}
UPDATE `table_name` SET `field2` = 2 WHERE `id` = 12345678
SQLSTATE[HY000]: General error: 1243 Unknown prepared statement handler (23039) given to mysqld_stmt_execute
不是必定觸發(fā),但是概率不小
然后我在網(wǎng)上搜了下報錯信息,tp框架有類似的問題,解決辦法是把PDO的PDO::ATTR_EMULATE_PREPARES屬性改成true
按照這樣把workerman源碼改下也正常了,但具體原因不清楚
PHP 7.2
mysql 5.7 有讀寫分離
我覺得可能是斷線重連時產(chǎn)生的問題。
prepared statement handler 這個是通過mysql預處理進行查詢;
類似一個查詢執(zhí)行2次命令,
第一次執(zhí)行:
PREPARE STMT FROM 'SELECT * FROM table LIMIT ?';
第二次執(zhí)行:
SET @a=1;EXECUTE STMT USING @a;
當?shù)谝淮螆?zhí)行后發(fā)生斷線重連時,運行的第二段sql則會報錯,因為對應的預處理已經(jīng)不存在了。
而設置PDO::ATTR_EMULATE_PREPARES = true,
則代表不使用mysql的預處理,通過PDO模擬預處理情況,最終只執(zhí)行一次。
如果要印證猜測是否成立,可以看看mysql的errlog