Skip to content

Poco::Data::Statement becomes unusable after exception #2287

@obiltschnig

Description

@obiltschnig

[Received via email]
[...]
The problem is that the Statement object cannot be used again after it throws. For example it throws when performing some operations on locked table etc.
The Statement object remains in ST_BOUND state and literally speaking the object is useless, and we cannot invoke execute on it once again.
We use it like this: (see below) -> the lambda is used to recreate the Statement object in case it throws:

 auto select = [&session, &sql, &keyCopy, &metadata, &data] () -> Poco::Data::Statement {
        Statement select (session);
        select << sql, use(keyCopy, "key"), into(metadata), into(data);
        return select;
    };
 
    if (executeTempFailureRetry(m_logger, m_name, select) == 0)
    {
        throw StorageEmptyException("No records for key \"" + key + "\"");
    }
…
    typedef std::function<Poco::Data::Statement()> StatementCreator;
    std::size_t SqliteStorage::executeTempFailureRetry(Poco::Logger &logger,
                                                       const std::string &name,
                                                       StatementCreator statementCreator)
    {
        int exec = 0;
        while (true)
        {
            try
            {
                ++exec;
                return statementCreator().execute();
            }
            catch (const Poco::Data::SQLite::DBLockedException &ex)
            {
                logger.warning("Could not temporarily (%d) access database table \"%s\": %s",
                               exec, name, ex.message());
                continue;
            }
            catch (const Poco::Data::SQLite::TableLockedException &ex)
            {
                logger.warning("Could not temporarily (%d) access database table \"%s\": %s",
                               exec, name, ex.message());
                continue;
            }
            catch (const Poco::Data::DataException &ex)
            {
                throw Storage::StorageErrorException(ex.message());
            }
        }
    }

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions