PDO的自動提交功能在autocommit關閉的MySQL上的啟用
P粉011912640
2023-08-08 15:23:46
<p>我剛被分配到只用了PDO的遺留PHP程式碼庫。 </p><p>連結是使用以下模式完成的:</p><p><br /></p>
<pre class="lang-php prettyprint-override"><code>// 連接到MySQL資料庫
$con = new mysqli($host, $user, $password, $database);
// Check connection
if ($con->connect_error) {
die("Connection failed: " . $con->connect_error);
}
$con->autocommit(true);
</code></pre>
<p>並且使用那個autocommit(true),即使MySQL伺服器配置為SET autocommit = 0,也按預期工作。 </p><p>現在我正在嘗試從普通SQL遷移到prepared statements,所以我寫了這個</p><p><br /></p>
<pre class="lang-php prettyprint-override"><code>$dsn = "mysql:host=$host;dbname=$database";
$pdo = new PDO($dsn, $user, $password);
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
</code></pre>
<p>與下面的範例函數</p>
<pre class="lang-php prettyprint-override"><code>function updateTeam($pdo, $name, $id)
{
try {
$data = [
'name' => $name,
'id' => $id
];
$sql = "UPDATE teams SET name = :name WHERE id=:id";
$stmt = $pdo->prepare($sql);
$stmt->execute($data);
// $pdo->commit();
}
catch (PDOException $e) {
db::$pdo->rollback();
error_log('Failed: ' . $e->getMessage() );
}
catch (Exception $exc) {
db::$pdo->rollback();
error_log('Failed: ' . $exc->getMessage());
}
}
</code></pre>
<p>不提交。我必須取消註釋$pdo->commit();才能使其工作,但這是我不想要的,因為這會迫使我更改應用程式中的每個查詢語句。 </p><p>我在PDO配置上漏掉了什麼?我試了var_dump($pdo->query('SELECT @@autocommit')->fetchAll()); 的結果是</p><p><code></code>< /p>
<pre class="brush:php;toolbar:false;">array(1) { [0]=> array(2) { ["@@autocommit"]=> string(1) "0" [0]=> string(1) "0" } }</pre>
<p><br /></p>
PDO的自動提交與MySQL的自動提交不相同。這意味著,如果在您的MySQL配置中將autocommit的值預設為0,它不會改變PDO::ATTR_AUTOCOMMIT的預設值。 PDO::ATTR_AUTOCOMMIT的預設值始終為true。
將PDO::ATTR_AUTOCOMMIT的值更改為與之相同的值或其他任何不是布林值或整數的值將被忽略。這意味著這兩個操作都是無操作:
#你可以透過停用和啟用PDO::ATTR_AUTOCOMMIT來欺騙它:
這將對MySQL伺服器進行兩次調用,應該會將MySQL的自動提交值設為1