Qt 事务回滚在 MySQL 上失败
Qt transactions rollback fails on MySQL
我正在尝试在 Qt 连接中使用事务,但我无法理解它们如何正常工作。
我的数据库是 MySQL 实例,table 使用 InnoDB 引擎,因此支持事务处理。
我写了一个小测试,在一个事务中我删除了 table 上的一条记录并最终创建了一个已经存在的 table。当创建脚本失败时,我尝试通过回滚来处理它。
我期望的是,回滚时,记录不会被删除。但是,我得到的是,一旦调用回滚函数,记录就会被删除。
#include <QApplication>
#include <QtSql>
#include <QtDebug>
int main( int argc, char **argv )
{
QApplication app( argc, argv );
QSqlDatabase db = QSqlDatabase::addDatabase( "QMYSQL" );
db.setHostName( QString("XXXXX")) ;
db.setDatabaseName( "db_test" );
db.setUserName( "X" );
db.setPassword( "X" );
QSqlDatabase::database().transaction();
QSqlQuery q;
if( !db.open() )
{
qDebug() << db.lastError();
qFatal( "Failed to connect." );
}
qDebug( "Connected!" );
q.prepare("DELETE FROM vendita WHERE matricola = :m and idOrdine = 530 and idStab = 1");
q.bindValue(":m","0032110275928");
if( !q.exec() ){
qDebug("error");
return 0;
}
//this fails, the table already exists
q.prepare( "CREATE TABLE test (id INTEGER UNIQUE PRIMARY KEY, firstname VARCHAR(30), lastname VARCHAR(30))" );
if( !q.exec() )
{
qDebug() << q.lastError();
bool res = QSqlDatabase::database().rollback();
qDebug() << res;
return 0;
}
else
{
qDebug() << "Table created!";
QSqlDatabase::database().commit();
}
db.close();
return 0;
}
but what I got is that, as soon the rollback function is invoked, the record is deleted.
CREATE TABLE 语句执行导致第一个查询(用于删除记录的查询)的隐式提交。因此,无论 CREATE TABLE 是否失败,您的记录都会被删除。
来自 https://dev.mysql.com/doc/refman/5.6/en/implicit-commit.html,
The statements listed in this section (and any synonyms for them) implicitly end any transaction active in the current session, as if you had done a COMMIT before executing the statement.
此外,请注意,无论如何您都无法回滚 CREATE TABLE,因为它是定义或修改数据库对象的数据定义语言 (DDL) 语句之一
我正在尝试在 Qt 连接中使用事务,但我无法理解它们如何正常工作。 我的数据库是 MySQL 实例,table 使用 InnoDB 引擎,因此支持事务处理。
我写了一个小测试,在一个事务中我删除了 table 上的一条记录并最终创建了一个已经存在的 table。当创建脚本失败时,我尝试通过回滚来处理它。
我期望的是,回滚时,记录不会被删除。但是,我得到的是,一旦调用回滚函数,记录就会被删除。
#include <QApplication>
#include <QtSql>
#include <QtDebug>
int main( int argc, char **argv )
{
QApplication app( argc, argv );
QSqlDatabase db = QSqlDatabase::addDatabase( "QMYSQL" );
db.setHostName( QString("XXXXX")) ;
db.setDatabaseName( "db_test" );
db.setUserName( "X" );
db.setPassword( "X" );
QSqlDatabase::database().transaction();
QSqlQuery q;
if( !db.open() )
{
qDebug() << db.lastError();
qFatal( "Failed to connect." );
}
qDebug( "Connected!" );
q.prepare("DELETE FROM vendita WHERE matricola = :m and idOrdine = 530 and idStab = 1");
q.bindValue(":m","0032110275928");
if( !q.exec() ){
qDebug("error");
return 0;
}
//this fails, the table already exists
q.prepare( "CREATE TABLE test (id INTEGER UNIQUE PRIMARY KEY, firstname VARCHAR(30), lastname VARCHAR(30))" );
if( !q.exec() )
{
qDebug() << q.lastError();
bool res = QSqlDatabase::database().rollback();
qDebug() << res;
return 0;
}
else
{
qDebug() << "Table created!";
QSqlDatabase::database().commit();
}
db.close();
return 0;
}
but what I got is that, as soon the rollback function is invoked, the record is deleted.
CREATE TABLE 语句执行导致第一个查询(用于删除记录的查询)的隐式提交。因此,无论 CREATE TABLE 是否失败,您的记录都会被删除。
来自 https://dev.mysql.com/doc/refman/5.6/en/implicit-commit.html,
The statements listed in this section (and any synonyms for them) implicitly end any transaction active in the current session, as if you had done a COMMIT before executing the statement.
此外,请注意,无论如何您都无法回滚 CREATE TABLE,因为它是定义或修改数据库对象的数据定义语言 (DDL) 语句之一