[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