c++ - 从 RAII 类的析构函数中抛出异常

标签 c++ database exception raii

我创建了一个类来封装数据库事务,以确保在抛出异常时回滚或提交。问题是创建和关闭事务都可能失败。由于事务正在析构函数中关闭,我如何在不抛出异常的情况下处理失败?显然,如果 TransactionLock 对象由于堆栈中某处抛出的异常而被销毁,这将导致程序终止。

// RAII class for database transaction
class TransactionLock {
public:
    TransactionLock(QSqlDatabase& db) :
        m_db(db),       
        m_query(db),
        m_committed(false)
    {
        bool ok = m_query.exec("BEGIN IMMEDIATE TRANSACTION");

        if (!ok)
        {
            throw IOException(m_query.lastError());
        }
    }

    ~TransactionLock() 
    {
        bool ok = m_committed ? m_db.commit() : m_db.rollback();

        // if (!ok) throw?
    }

    void commitTransaction()
    { 
        m_committed = true;
    }       

private:
    QSqlDatabase& m_db; 
    QSqlQuery m_query;
    bool m_committed;   
};

最佳答案

你永远不应该在析构函数中抛出。不仅因为异常堆栈展开可以调用析构函数,还因为它在逻辑上毫无意义。

你无法阻止对象被破坏,所以异常不会给你任何东西。在您的特定情况下,您需要重新设计您的类(class)。标准方法通常是在析构函数中进行自动回滚。提交事务是一个带有错误代码的显式操作。

关于c++ - 从 RAII 类的析构函数中抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35015915/

相关文章:

c++ - 列表迭代器不兼容断言失败

sql - 如何在 SSMS 中显示批量中单个查询的实际查询计划?

c# - 检查第 3 个位置的整数是否为 5

java - Java 中的 C# InvalidEnumArgumentException

java - throw 和 catch 子句

c++ - 使用可变修改类型实例化模板

c++ - 将变量插入 vector , vector 中该点的值会随着变量的改变而改变

c++ - 有向图中的高效搜索

java - 如何在 JDBC 调用 MySQL 数据库时指定毫秒超时?

php - Mysql条件查询