我正在尝试在Qt连接中使用事务,但我无法理解它们如何正常工作。 我的数据库是MySQL实例,表使用InnoDB引擎,因此支持事务。
我写了一个小测试,在一个事务中,我删除了一个表上的记录,最终创建了一个已经存在的表。当创建脚本失败时,我尝试通过回滚来处理它。
我期待的是,回滚后,记录不会被删除。但是,我得到的是,一旦调用回滚函数,记录就会被删除。
#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;
}
答案 0 :(得分:1)
但我得到的是,一旦调用回滚函数,记录就会被删除。
CREATE TABLE语句执行会导致第一个查询(您用于删除记录的查询)的隐式提交。因此,无论CREATE TABLE是否失败,都会删除您的记录。
来自https://dev.mysql.com/doc/refman/5.6/en/implicit-commit.html,
本节中列出的语句(以及它们的任何同义词)隐式结束当前会话中活动的任何事务,就像在执行语句之前已完成COMMIT一样。
另请注意,无论如何都无法回滚CREATE TABLE,因为它是定义或修改数据库对象的数据定义语言(DDL)语句之一