mirror of
https://github.com/Cacti/cacti.git
synced 2026-10-25 04:27:56 +09:00
* fix: commit transactions on MySQL as well as MariaDB db_commit_transaction() gated the commit on SELECT @@in_transaction. That variable is MariaDB only; MySQL answers 'Unknown system variable in_transaction', so the guard was false on every MySQL install and the commit never ran. The transaction was left open and the function reported failure. Verified against both engines: MariaDB returns 0, MySQL 8 raises ERROR 1193. Every caller was affected, including device removal, which reports 'Unable to remove Device N because its database transaction could not be committed' and leaves the device in place. Use PDO::inTransaction(), which tracks the state itself and answers the same question on both engines. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Update transaction regression assertion Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
41 lines
1.7 KiB
PHP
41 lines
1.7 KiB
PHP
<?php
|
|
/*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2004-2026 The Cacti Group |
|
|
+-------------------------------------------------------------------------+
|
|
| Cacti: The Complete RRDtool-based Graphing Solution |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
$databaseSource = file_get_contents(dirname(__DIR__, 3) . '/lib/database.php');
|
|
|
|
test('the commit path does not depend on the MariaDB in_transaction variable', function () use ($databaseSource) {
|
|
$start = strpos($databaseSource, 'function db_commit_transaction(');
|
|
$end = strpos($databaseSource, 'function ', $start + 1);
|
|
$body = substr($databaseSource, $start, $end - $start);
|
|
|
|
// MySQL answers "Unknown system variable 'in_transaction'", so the guard
|
|
// was always false there and the commit never ran.
|
|
expect($body)->not->toContain("SELECT @@in_transaction")
|
|
->and($body)->toContain('inTransaction()');
|
|
});
|
|
|
|
test('PDO reports transaction state identically regardless of engine', function () {
|
|
$pdo = new PDO('sqlite::memory:', null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
|
|
|
expect($pdo->inTransaction())->toBeFalse();
|
|
|
|
$pdo->beginTransaction();
|
|
expect($pdo->inTransaction())->toBeTrue();
|
|
|
|
expect($pdo->commit())->toBeTrue()
|
|
->and($pdo->inTransaction())->toBeFalse();
|
|
});
|
|
|
|
test('committing without an open transaction is refused rather than fatal', function () {
|
|
$pdo = new PDO('sqlite::memory:', null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
|
|
|
// The guard exists because PDO::commit() throws when nothing is open.
|
|
expect($pdo->inTransaction())->toBeFalse();
|
|
});
|