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

Deprecate PingableConnection in favor of handling lost connection #4119

Merged
merged 3 commits into from
Jun 27, 2020

Conversation

morozov
Copy link
Member

@morozov morozov commented Jun 27, 2020

Q A
Type improvement, deprecation
BC Break no
  1. The "ping" functionality in the DBAL is really questionable. The only way to check if the connection is alive is to execute a query. And even if one query succeeds or fails, it doesn't guarantee that another one will succeed or fail as well. Additionally, it's only supported by mysql-based drivers.
  2. Instead, the wrapper connection can handle a ConnectionLost exception if it's reported by the driver. This means the behavior is happening automatically from now on.
  3. Statement constructors are marked internal. It will allow to remove the dependency of the wrapper Statement on the wrapper Connection similarly to how it was done with the oci8 driver in Removed the OCI8Connection::getExecuteMode() method #3808. The new Connection::handle*() internal methods are temporary and will be moved to an ExceptionHandler after refactoring.

lib/Doctrine/DBAL/Connection.php Outdated Show resolved Hide resolved
lib/Doctrine/DBAL/Connection.php Outdated Show resolved Hide resolved
@morozov morozov force-pushed the deprecate-pingable branch from 8658105 to 1953b2f Compare June 27, 2020 14:49
@morozov morozov force-pushed the deprecate-pingable branch from 1953b2f to 0a5bac1 Compare June 27, 2020 14:58
@healerz
Copy link

healerz commented Sep 22, 2020

Hi @morozov
I have a question regarding this change. In our project, we use ping() to ensure the connection is not lost:

if (false === $this->ping($connection)) {
  $connection->close();
  $connection->connect();
}

Correct me if I'm wrong, but if I understand this change correctly, the difference is that the connection gets closed properly if the connection is lost. But it doesn't execute the query again, in such a case. So it only ensures that the next query succeeds again.
What is the alternative to ensure the connection is not lost due to a connection timeout, so we can safely execute our actual query?
Or is the solution to execute a dummy query and catch the ConnectionLost exception?
Even though I do agree with your reasoning above :)

@morozov
Copy link
Member Author

morozov commented Sep 22, 2020

Correct me if I'm wrong, but if I understand this change correctly, the difference is that the connection gets closed properly if the connection is lost. But it doesn't execute the query again, in such a case. So it only ensures that the next query succeeds again.

Sounds correct.

What is the alternative to ensure the connection is not lost due to a connection timeout, so we can safely execute our actual query?

There's no way to ensure that it's not lost. Even if the query you use to probe the connection succeeds, there's no guarantee that the real query will.

Or is the solution to execute a dummy query and catch the ConnectionLost exception?

See the above. The solution is to catch the ConnectionLost exception and handle it depending on the query. E.g. it is safe to re-execute a SELECT but isn't safe to re-execute an INSERT w/o first checking the current state of the database (the connection may fail after the row has been inserted).

@healerz
Copy link

healerz commented Sep 23, 2020

@morozov thx for your reply. Makes all sense.

beberlei added a commit to beberlei/dbal that referenced this pull request Mar 7, 2021
beberlei added a commit to beberlei/dbal that referenced this pull request Mar 11, 2021
beberlei added a commit to beberlei/dbal that referenced this pull request Mar 22, 2021
@flmommens
Copy link

I catch the exception and immediately retry my SELECT query but get the same exception again.

@morozov
Copy link
Member Author

morozov commented Jun 23, 2021

@flmommens please file a separate issue and provide all the details of the failure. The basic case is covered with this test:

public function testConnectionLost(): void
{
$this->connection->query('SET SESSION wait_timeout=1');
sleep(2);
$query = $this->connection->getDatabasePlatform()
->getDummySelectSQL();
try {
// in addition to the error, PHP 7.3 will generate a warning that needs to be
// suppressed in order to not let PHPUnit handle it before the actual error
@$this->connection->executeQuery($query);
} catch (ConnectionLost $e) {
self::assertEquals(1, $this->connection->fetchOne($query));
return;
}
self::fail('The connection should have lost');
}

@vudaltsov
Copy link

@morozov, why don't you check instanceof ConnectionException?

@vudaltsov
Copy link

I think, I got it. ConnectionException is mainly thrown when credentials are invalid, so reconnecting will not help.

kdambekalns added a commit to kdambekalns/flow-development-collection that referenced this pull request Jan 25, 2022
Since DBAL 2.11.0 retry and reconnecting lost connections happens
automatically, ping() will be removed in DBAL 3, see the PR at
doctrine/dbal#4119

Thus this code is dropped, as since 7.0.0 we require a newer DBAL
version.
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 23, 2022
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 24, 2022
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 24, 2022
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 24, 2022
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 24, 2022
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 24, 2022
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 24, 2022
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 24, 2022
mmadariaga added a commit to irontec/ivozprovider that referenced this pull request Mar 25, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants