QT QSqlite database transaction usage and precautions
QSqlite's transaction (transaction)
Transaction: All operations on the database are either executed or not executed at all;
1. Determine whether your database has transaction functions:
After the database connection is successful, print the following: result true | false
qDebug() <<"this DB hasFeature:Transaction:" <<db.driver()->hasFeature(QSqlDriver::Transactions);
2. If it is true, you can use to open:
The return value here is also bool type, you can print it to see the result true | false
bool transaction_begin;
transaction_begin= db.transaction(); //开启事务
//打印事务开启结果 bool
qDebug() << " transaction_begin : "<<transaction_begin ;
sql statement execution
The general operation is to add, delete and modify the actual object, and the check is unnecessary.
query.prepare(QString("INSERT INTO TANLE_NAME("........")");
After doing the above insertion, you can submit it. Of course, if there is an error in the stored procedure, you need to rollback rollback(); Commite again if there is no error;
then check the print result
bool success = query.exec();
query.finish(); //资源释放
QSqlError lastError = query.lastError(); //错误信息
if(!success)
{
qDebug() << QObject::tr("TANLE add %1 tr lose: ").arg(i) << lastError;
db.rollback(); //回滚 返回false
return false;
}
else
{
qDebug() << QObject::tr("TEST_RESULT add %1 tr success").arg(i);
}
commit_result = db.commit(); //提交事务
qDebug() << "commit_result---------- : " << commit_result;
db.close();
db.removeDatabase(nmDatabase);
The above are normal operations
The above operation knowledge is an operation, if it needs to be stored multiple times, if it is regular, a for loop is allowed, just add a for loop directly to the sql statement, but if it is required to operate in separate classes (the database is a separate class, Create this database class in other classes, and then call the insert() function here, and call the insert() function here cyclically.), the transaction processing cannot be realized.
Look at the code: loop call
while (iter != Trss.end()) //用while循环 如果不是结尾就一直添加 并且递增
{
userDB->addOneTR(iter.value());
iter ++;
}
addOneTR() is added as follows:
for(i = 0;i<TRS.size();i++)
{
query.prepare(QString("INSERT INTO TANLE_NAME("........")");
}
The above double loop addition will cause normal data storage when interrupted during debugging, and the printing result will be false.
the reason:
After investigation, the reasons are: ①The database connection should be connected before the transaction is opened; ②The database is closed, disconnected, and should be disconnected after commit.
But the database class here is extra, so I call the method of the database class at the same time, and userDB is my database class pointer.
//创建连接
userDB->createConnection2(userDB->nmDatabase);
//查看是否允许事务的使用
qDebug() <<"this DB hasFeature:Transaction:" <<userDB->db.driver()->hasFeature(QSqlDriver::Transactions);
//开启事务
transaction_begin = userDB->db.transaction();
//打印事务开启结果 bool
qDebug() << " transaction_begin : "<<transaction_begin ;
QMap<int, QVector<TEST_RESULT>>::iterator iter = Trss.begin(); //创建迭代器 是测试结果的第一个值
qDebug() << " Begin insert One Wpnl PCB Result---------------------" ;
while (iter != Trss.end()) //用while循环 如果不是结尾就一直添加 并且递增
{
userDB->addOneTR(iter.value());
iter ++;
}
//commit提交事务
commit_result = userDB->db.commit();
//打印提交结果
qDebug() << " commit_result : "<<commit_result ;
//关闭数据库
userDB->db.close();
//移除连接
userDB->db.removeDatabase(userDB->nmDatabase);
qDebug() << Trss.value(0).at(0).barcode << " End insert One Wpnl PCB Result---------------------" ;