Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix test of timeout PDOException: Packets out of order #352

Merged
merged 14 commits into from
Aug 30, 2024
Merged
2 changes: 1 addition & 1 deletion .github/workflows/ansi-mode.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
run: composer update --no-interaction --no-progress --optimize-autoloader --ansi

- name: Run tests with phpunit with code coverage.
run: vendor/bin/phpunit --coverage-clover=coverage.xml --colors=always
run: vendor/bin/phpunit --coverage-clover=coverage.xml --colors=always --display-warnings --display-deprecations

- name: Upload coverage to Codecov.
uses: codecov/codecov-action@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-mariadb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:
run: composer update --no-interaction --no-progress --optimize-autoloader --ansi

- name: Run tests with phpunit with code coverage.
run: vendor/bin/phpunit --coverage-clover=coverage.xml --colors=always
run: vendor/bin/phpunit --coverage-clover=coverage.xml --colors=always --display-warnings --display-deprecations

- name: Upload coverage to Codecov.
uses: codecov/codecov-action@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
run: composer update --no-interaction --no-progress --optimize-autoloader --ansi

- name: Run tests with phpunit with code coverage.
run: vendor/bin/phpunit --coverage-clover=coverage.xml --colors=always
run: vendor/bin/phpunit --coverage-clover=coverage.xml --colors=always --display-warnings --display-deprecations

- name: Upload coverage to Codecov.
uses: codecov/codecov-action@v3
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
- Chg #339: Replace call of `SchemaInterface::getRawTableName()` to `QuoterInterface::getRawTableName()` (@Tigrov)
- Enh #342: Add JSON overlaps condition builder (@Tigrov)
- Enh #344: Update `bit` type according to main PR yiisoft/db#860 (@Tigrov)
- Enh #347: Raise minimum PHP version to `^8.1` with minor refactoring (@Tigrov)
- Bug #349, #352: Restore connection if closed by connection timeout (@Tigrov)
- Enh #347, #353: Raise minimum PHP version to `^8.1` with minor refactoring (@Tigrov)
- Bug #349: Restore connection if closed by connection timeout (@Tigrov)

Expand Down
7 changes: 5 additions & 2 deletions src/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ protected function queryInternal(int $queryMode): mixed
try {
return parent::queryInternal($queryMode);
} catch (IntegrityException $e) {
if (str_starts_with($e->getMessage(), 'SQLSTATE[HY000]: General error: 2006 ')) {
$this->db->close();
if (
str_starts_with($e->getMessage(), 'SQLSTATE[HY000]: General error: 2006 ')
&& $this->db->getTransaction() === null
) {
$this->cancel();
$this->db->close();

return parent::queryInternal($queryMode);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace Yiisoft\Db\Mysql;

use Exception;
use Psr\Log\LogLevel;
use Throwable;
use Yiisoft\Db\Driver\Pdo\AbstractPdoConnection;
use Yiisoft\Db\Driver\Pdo\PdoCommandInterface;
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
Expand All @@ -30,8 +30,8 @@ public function close(): void

// Solution for close connections {@link https://stackoverflow.com/questions/18277233/pdo-closing-connection}
try {
$this->pdo->query('KILL CONNECTION_ID()');
} catch (Exception) {
$this->pdo->exec('KILL CONNECTION_ID()');
} catch (Throwable) {
}

$this->pdo = null;
Expand Down
20 changes: 18 additions & 2 deletions tests/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Throwable;
use Yiisoft\Db\Connection\ConnectionInterface;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\IntegrityException;
use Yiisoft\Db\Exception\InvalidConfigException;
use Yiisoft\Db\Exception\NotSupportedException;
use Yiisoft\Db\Mysql\Tests\Support\TestTrait;
Expand Down Expand Up @@ -132,12 +133,27 @@ public function testRestartConnectionOnTimeout(): void

$db->createCommand('SET SESSION wait_timeout = 1')->execute();

sleep(1);
sleep(2);

$result = $db->createCommand("SELECT '1'")->queryScalar();
$result = $db->createCommand('SELECT 1')->queryScalar();

$this->assertSame('1', $result);

$db->close();
}

public function testNotRestartConnectionOnTimeoutInTransaction(): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were going to restart it without error.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a query in a transaction it is not correct to retry the query in the new connection out of the transaction.
We can close the old connection but the error will still be thrown.

{
$db = $this->getConnection();
$db->beginTransaction();

$db->createCommand('SET SESSION wait_timeout = 1')->execute();

sleep(2);

$this->expectException(IntegrityException::class);
$this->expectExceptionMessage('SQLSTATE[HY000]: General error: 2006 MySQL server has gone away');

$db->createCommand('SELECT 1')->queryScalar();
}
}
Loading