[odb-users] Understanding odb::recoverable exceptions
Boris Kolpackov
boris at codesynthesis.com
Mon May 11 07:17:19 EDT 2020
Javier Gutierrez <javier.gutierrez at web.de> writes:
> I did my tests with MySQL.
> It seems that when the database is not available, opening a new transaction
> does not throw a odb::recoverable but rather a "Can't connect to MySQL
> server on ..." (odb::exception?).
> If the database connection is lost after opening the transaction, then a
> odb::recoverable is thrown. In this case your piece of code attempts a retry
> by running the transaction again. But as said, this does not throw a
> odb::recoverable so it goes immediately out of the loop never reaching the
> max_retries.
>
> Am I missing something ?
These situations are not exactly/always the same, right? The idea here is
that if the connection is lost mid-transaction that you will probably
want to try to retry it at least once (because things were working just
a moment ago). On the other hand, if you could not connect to the database
in the first place, this is as likely a permanent error as transient.
Also, keep in mind that all these exceptions are mapped from error codes
returned by the MySQL client library. So to understand the exact semantics
for a particular database don't be afraid to look at the source code. For
MySQL, the relevant code is in error.cxx:
switch (e)
{
case CR_OUT_OF_MEMORY:
{
throw bad_alloc ();
}
case ER_LOCK_DEADLOCK:
{
throw deadlock ();
}
case CR_SERVER_LOST:
case CR_SERVER_GONE_ERROR:
{
c.mark_failed ();
throw connection_lost ();
}
case CR_UNKNOWN_ERROR:
{
c.mark_failed ();
}
// Fall through.
default:
{
...
throw database_exception (e, sqlstate, msg);
}
}
More information about the odb-users
mailing list