1. 程式人生 > >Qt模組化筆記之sql——事務處理的實現

Qt模組化筆記之sql——事務處理的實現

所謂事務處理,即將一些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();
        }


}