You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

QT连接Access数据库使用事务报错:无法禁用自动提交

解决Qt连接Access数据库时事务启动报错的问题

看起来你遇到的问题是Qt用QODBC驱动连接Access .mdb数据库时,明明驱动声称支持事务,但启动事务时却报无法禁用自动提交的错误。我之前也处理过类似的Access ODBC兼容问题,给你几个可行的解决思路:

1. 调整连接字符串参数,解决驱动服务冲突

这个错误很大概率是Access ODBC驱动的自动服务和Qt事务机制冲突导致的。尝试在连接字符串里添加OLE DB Services=-4参数,禁用驱动的自动事务管理服务,让Qt来接管事务控制:

m_db = QSqlDatabase::addDatabase("QODBC"); 
QString strPathDDBB = "DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=" + QCoreApplication::applicationDirPath() + "/galibo.mdb;OLE DB Services=-4"; 
m_db.setDatabaseName(strPathDDBB); 
if (!m_db.open()) { 
    QMessageBox::critical(0, QObject::tr("Database Error"), m_db.lastError().text()); 
}

另外,也可以加上Mode=ReadWrite参数明确指定数据库的读写权限,避免因权限问题导致事务无法启动。

2. 手动提前禁用自动提交

Qt调用transaction()时会尝试关闭自动提交,但有些版本的Access ODBC驱动不允许在连接打开后动态修改这个属性。你可以在数据库打开后,手动先调用驱动的setAutoCommit()方法关闭自动提交,再启动事务:

bool feature = m_db.driver()->hasFeature(QSqlDriver::Transactions);
if (m_db.isOpen()) {
    // 先手动禁用自动提交
    if (!m_db.driver()->setAutoCommit(false)) {
        qDebug() << "Failed to disable autocommit:" << m_db.lastError().text();
        return false;
    }
    // 再启动事务
    if (!m_db.transaction()) {
        QString error = "An error occurred while creating the transaction in the database\n";
        error += m_db.lastError().text();
        qDebug() << error;
        return false;
    }
}

3. 更换为QOLEDB驱动

如果QODBC驱动的兼容性问题始终无法解决,可以尝试切换到QOLEDB驱动(前提是你的Qt版本支持这个驱动),OLE DB驱动对Access的事务支持更原生:

m_db = QSqlDatabase::addDatabase("QOLEDB");
// 使用Jet OLE DB 4.0驱动(适合.mdb格式)
QString strPathDDBB = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + QCoreApplication::applicationDirPath() + "/galibo.mdb;Persist Security Info=False";
m_db.setDatabaseName(strPathDDBB);
if (!m_db.open()) {
    QMessageBox::critical(0, QObject::tr("Database Error"), m_db.lastError().text());
}

注意:64位系统上如果没有安装32位的Jet驱动,可能需要换成Microsoft.ACE.OLEDB.12.0驱动(支持.mdb和.accdb)。

4. 检查数据库的锁定状态

确保你的.mdb数据库没有被其他程序以独占模式打开,也没有设置为只读权限。如果数据库处于只读或独占状态,事务肯定无法启动。你可以手动打开数据库确认一下,或者在连接字符串里加上Share Deny None参数来避免锁定冲突:

// 追加到连接字符串末尾
+ ";Share Deny None"

补充说明

虽然hasFeature(QSqlDriver::Transactions)返回true,但这只是Qt检测到驱动声称支持事务,实际Access ODBC驱动在某些场景下(比如默认启用的自动服务)会限制事务的启动,所以需要通过调整连接参数或更换驱动来绕过这个问题。

内容的提问来源于stack exchange,提问作者PinTxO

火山引擎 最新活动