从 RAII class 的析构函数中抛出异常
Throwing exception from destructor of RAII class
我创建了一个 class 来封装数据库事务,以确保它在抛出异常时回滚或提交。问题是创建和关闭事务都可能失败。由于事务正在析构函数中关闭,我如何在不抛出异常的情况下处理失败?显然,如果 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。标准方法通常是在析构函数中进行自动回滚。提交事务是一个带有错误代码的显式操作。
我创建了一个 class 来封装数据库事务,以确保它在抛出异常时回滚或提交。问题是创建和关闭事务都可能失败。由于事务正在析构函数中关闭,我如何在不抛出异常的情况下处理失败?显然,如果 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。标准方法通常是在析构函数中进行自动回滚。提交事务是一个带有错误代码的显式操作。