在销毁 MySQL 连接器/C++ 类对象后构造一个

Constructing a MySQL Connector/C++ class object after one is destroyed

提问人:astronomerdave 提问时间:11/7/2023 最后编辑:astronomerdave 更新时间:11/7/2023 访问量:43

问:

使用MySQL Connector/C++ 8.0,我定义了一个Database类并构造该类的对象以连接到数据库。这很好用。如果那个对象被破坏了,而我试图构造另一个对象,那么它就会失败。

这是课程:

  class Database {
    private:
      std::unique_ptr<mysqlx::Session> _session;
      std::unique_ptr<mysqlx::Table>   _table;
      std::unique_ptr<mysqlx::Schema>  _schema;
    public:
      Database( std::string host,
                int         port,
                std::string user,
                std::string pass,
                std::string schema,
                std::string table ) {
        _session = std::make_unique<mysqlx::Session> ( mysqlx::SessionOption::HOST, host,
                                                       mysqlx::SessionOption::PORT, port,
                                                       mysqlx::SessionOption::USER, user,
                                                       mysqlx::SessionOption::PWD,  pass );

        _schema  = std::make_unique<mysqlx::Schema>( *_session, schema );
        _table   = std::make_unique<mysqlx::Table>( _schema->getTable( table ) );

        void write( std::map<std::string, std::string> data );  // details not pertinent here

        // close might be overkill? shouldn't things get cleaned up when
        // the object goes out of scope and is deconstructed?
        //
        inline void close() { _session->close(); _session.reset(); _table.reset(); _schema.reset(); }
      }
  }

我可以在线程中实例化 Database 对象(一次只能启动一个这样的“数据库”线程,因此永远不会有任何争用的风险),例如:

  void SomeClass::dothread_db( host,port,... etc.. ) {
    try {
      Database::Database database(host,port,user,pass,schema,table);
      while (condition ) {
        database.write(...);
        // things can change the condition
      }

      database.close();  // is this even needed?

    } catch etc..

    return;
  }

我可以生成一次,它连接到数据库并整天写入数据库,但是如果满足条件使其完成,然后我尝试生成另一个,我将得到两个可能的错误之一:dothread_db

CDK Error: OpenSSL: error:00000000:lib(0):func(0):reason(0)

CDK Error: Bad file descriptor (generic:9)

当它尝试构造 Database 对象时。我在日志中没有看到任何消息。只有在遇到这个问题后,我才添加了 Database::close() 函数,以防万一这在某种程度上是问题所在,但使用它没有任何(明显的)区别。/var/log/mysql/

C++ mysql 连接器

评论

0赞 Barmar 11/7/2023
创建实例时未指定构造函数参数,因此使用默认构造函数,并且它从不初始化任何成员变量。因此,当您调用 时,您有未初始化的变量。Databasedatabase.close()
0赞 astronomerdave 11/7/2023
对不起,这是我输入的示例中的疏忽。我确实使用所需的参数构建它;没有其他构造函数。此后,我编辑了这个问题以反映这一点。
0赞 pptaszni 11/7/2023
也许不是问题,但您应该以相反的顺序关闭/销毁您的对象。例如,在您的情况下,持有对 的引用,因此销毁之前可能是 UB(取决于实现细节)。_schema_session_session
0赞 astronomerdave 11/8/2023
它必须是谁生成 dothread_db() 线程。我发现,如果dothread_db在程序启动时从主线程生成,那么它总是没问题的。我的问题是,当dothread_db停止并重新生成时,我收到错误,但问题不在于重新启动它。问题出在我开始的地方。如果我从不从 main() 线程生成它,而是从另一个线程(例如侦听命令的线程)生成它,那么数据库对象构造很好,但写入数据库会给出 CDK 错误:错误的文件描述符 (generic:9),即使这是第一次。

答: 暂无答案