今天看书到数据库章节,演示了数据库的连接,数据的增、删、改、查,都非常的简单,没有特殊的地方。
QSqlQuery封装的很好,与.NET中封装的各种Helper差不多,很方便使用;同时是桌面开发,一个应用程序在其生命周期一个数据库连接,和Delphi的DataModel一样。综合这些,非常亲切,认为Qt的数据库:简单、方便。
悲惨的命运来了,当我演示到数据库事物的时候。
一、经验的数据库事物管理代码
db.transaction();
try
{
query.exec("insert into student values(0,'LiMing')");
query.exec("insert into student values(1,'LiuTao')");
query.exec("insert into student values(2,'WangHong')");
db.commit();
}
catch (QString exception)
{
db.rollback();
qDebug()<<"createConnection error"<<query.lastError();
return false;
}
用try{}catch{}进行事物的提交和回滚,这是不行的。
二、根据书上的例子编写代码
if (QSqlDatabase::database().transaction()){
query.exec("insert into student values(4,'LiMing4')");
query.exec("insert into student values(5,'LiuTao4')");
query.exec("insert into student values(6,'WangHong5')");
if (!QSqlDatabase::database().commit()){
qDebug() << QSqlDatabase::database().lastError(); //提交
if(!QSqlDatabase::database().rollback()){
qDebug() << QSqlDatabase::database().lastError(); //回滚
}
}
}
哦,还是没有实现回滚。
三、根据经验,构造代码
if (db.transaction()){
query.exec("insert into student values(4,'LiMing4')");
query.exec("insert into student values(5,'LiuTao5')");
query.exec("insert into student values(6,'WangHong6')");
if (!db.commit()){
qDebug() << db.lastError(); //提交
if(!db.rollback()){
qDebug() << db.lastError(); //回滚
}
}
}
哦,不行。
四、正确的垃圾代码
if (db.transaction()){
bool ok1=query.exec("insert into student values(1,'LiMing1')");
bool ok2=query.exec("insert into student values(2,'LiuTao2')");
bool ok3=query.exec("insert into student values(3,'WangHong3')");
bool ok4=query.exec("update student set name='LiMing1_1' where id=1");
if (ok1&&ok2&&ok3&&ok4){
if (!db.commit()){
qDebug() <<"提交失败"<< db.lastError(); //提交
if(!db.rollback()){
qDebug() << db.lastError(); //回滚
}
}
else {
qDebug()<<"提交成功";
}
}
else
{
//有错误,回滚
if(!db.rollback()){
qDebug()<<"回滚失败"<< db.lastError(); //回滚
}
else {
qDebug()<<"回滚成功";
}
}
}
网上疯狂的查找,在《 Qt: 事务处理片断》http://www.cppblog.com/biao/archive/2009/07/24/91017.html中,终于查到,对代码改造。
哦,90年代的程序员,没有throw Exception概念。这个东西,有好有坏;坏处大于好处。这都没有处理好,还谈什么事物的级别.