Qt模組化筆記之sql——事務處理的實現
阿新 • • 發佈:2019-02-06
所謂事務處理,即將一些sql語句“分塊”執行。如果都執行成功了,我們可以commit提交它(讓它真正執行),如果其中一處有誤,我們可以rollback回滾它(讓這個塊裡的語句都相當於沒有執行)。
網上找到的一個比較生動的例子,可以更好理解它的應用:
舉例:你去銀行轉賬,轉賬我們有兩步吧,從你賬戶中取出錢再往他賬戶中加錢。那這兩步銀行是必須要確保正確無誤的進行的。要被看做成一個事務。其中任何一步出錯就算是轉賬失敗,但可能你這時是已經從你賬戶中扣了錢了,又沒往他賬戶里加錢?怎麼辦算了?你不肯吧。所以銀行會事務回滾,不儲存你剛才的操作,即恢復到你沒轉賬之前的狀態。
一個事務過程為:開啟事務——執行語句——提交或回滾事務。
我們可以使用兩種方式實現事務處理:
1,sql資料庫語句:
if(db.open()) { qDebug()<<"開啟成功"; QSqlQuery transaction_start; QSqlQuery transaction_COMMIT; QSqlQuery transaction_ROLLBACK; QSqlQuery query_insert; QSqlQuery query_delete; transaction_start.exec("START TRANSACTION");//開始事務。使用BEGIN也可以 bool ok1=query_insert.exec("insert into tb_books values('4','Qt模組化筆記4','4')"); bool ok2=query_delete.exec("delete from tb_books where isbn='20131101183101' "); qDebug()<<ok1<<ok2; if(ok1 && ok2) { transaction_COMMIT.exec("COMMIT");//提交 }else { transaction_ROLLBACK.exec("ROLLBACK");//回滾 } }
當query_insert和query_delete成功執行時,提交它,讓它真正執行……。
如果修改這條語句:
bool ok2=query_delete.exec("delete from tb_books where isbn='20131101183101' ");
中的tb_books為tb_none後,由於沒有tb_none這個表格,導致ok2為false。這時回滾事務,insert操作雖然用exec()執行了,但經過回滾後,它又撤消了,資料庫中不會插入資料。細心的讀者可以發現,我們沒有在QSqlQuery例項化時直接將語句寫入。而是在exec()中執行。這是因為,如果例項化時寫入,在我們想象中,所有語句只是被初始化了,然而commit提交時,它們都會被執行。例如我們這樣:
QSqlQuery query_insert("insert into tb_books values('4','Qt模組化筆記4','4')");
bool ok1=query_insert.exec();
if(ok1 && ok2)
{
transaction_COMMIT.exec("COMMIT");//提交
}else
{
transaction_ROLLBACK.exec("ROLLBACK");//回滾
}
insert操作會進行兩次,導致我們不想的結果出現,插入了兩行相同的資料。
2,qt database類自帶的三個函式:transaction(),commit(),rollback()可以省掉我們寫一些sql語句的時間……
if(db.open())
{
qDebug()<<"開啟成功";
QSqlQuery query_insert;
QSqlQuery query_delete;
db.transaction();
bool ok1=query_insert.exec("insert into tb_books values('4','Qt模組化筆記4','4')");
bool ok2=query_delete.exec("delete from tb_books where isbn='20131101183101' ");
qDebug()<<ok1<<ok2;
if(ok1 && ok2)
{
db.commit();
}else
{
db.rollback();
}
}