• 6289阅读
  • 10回复

事务处理回滚问题 [复制链接]

上一主题 下一主题
离线searchcai
 

只看楼主 倒序阅读 楼主  发表于: 2013-08-09
    sqlhelper->Transaction();


    bool bRet = sqlhelper->m_sqlQuery.exec(strSql1);
    if(!bRet)
    {
        ----------------------------这个地方需要加 sqlhelper->Rollback();吗?----------------
        QSqlError sqlError = sqlhelper->GetLastQueryError();
        ::LogError(__FILE__, __LINE__, sqlError.number(), sqlError.text());
        return false;
    }


    bRet = sqlhelper->m_sqlQuery.exec(strSql2);
    if(!bRet)
    {
        sqlhelper->Rollback();
        QSqlError sqlError = sqlhelper->GetLastQueryError();
        ::LogError(__FILE__, __LINE__, sqlError.number(), sqlError.text());
        return false;
    }
    sqlhelper->Commit();
    return true;
在线XChinux

只看该作者 1楼 发表于: 2013-08-09
先要看sqldriver是否支持事务处理,如果不支持,就得另想办法.
如果支持事务的话,你上面你说的那个,应该不用管,commit时就会失败,然后rollback就行了.
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线searchcai

只看该作者 2楼 发表于: 2013-08-09
支持事务。
我的意思是第一句SQL执行错了需要回滚吗?我自己认为第一条既然执行错了,就没有必要回滚了,直接return了,下面的SQL也肯定不执行了,不知道这样会不会有其他导致死锁问题的发生?
离线searchcai

只看该作者 3楼 发表于: 2013-08-09
老大熟悉QML吗?
我这边有个触控项目,看你感兴趣不?
离线searchcai

只看该作者 4楼 发表于: 2013-08-09
顺便再问一个问题:
    m_db = QSqlDatabase::addDatabase("QMYSQL",g_strConnectionName);
    m_db.setHostName(g_strIP);
    m_db.setPort(g_nPort);
    m_db.setUserName(g_strUserName);
    m_db.setPassword(g_strPassword);
    m_db.setDatabaseName(g_strDBName);

    m_db.setConnectOptions(QString("CLIENT_INTERACTIVE=2880"));

    if( m_db.open() )
    。。。


为什么提示   QMYSQLDriver::open: Illegal connect option value 'CLIENT_INTERACTIVE=2880'啊?
在线XChinux

只看该作者 5楼 发表于: 2013-08-09
引用第2楼searchcai于2013-08-09 15:28发表的  :
支持事务。
我的意思是第一句SQL执行错了需要回滚吗?我自己认为第一条既然执行错了,就没有必要回滚了,直接return了,下面的SQL也肯定不执行了,不知道这样会不会有其他导致死锁问题的发生?

你中间想退出也可以,那就rollback,比如.

if (db.transaction())
{
   bool bBreak = false;
    while (true)
   {
       if (!db.exec(sql1))
        { bBreak = true;   break;}
       if (!db.exec(sql2))
        { bBreak = true;   break;}
       break;
   }
    if (bBreak)
    {  
         db.rollback();
    }
    else  if ( !db.commit())
    {
         db.rollback();
    }
}
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
在线XChinux

只看该作者 6楼 发表于: 2013-08-09
引用第4楼searchcai于2013-08-09 15:31发表的  :
顺便再问一个问题:
    m_db = QSqlDatabase::addDatabase("QMYSQL",g_strConnectionName);
    m_db.setHostName(g_strIP);
    m_db.setPort(g_nPort);
    m_db.setUserName(g_strUserName);
.......

这个需要你自己查资料.很久没做过MySQL的了.
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
在线XChinux

只看该作者 7楼 发表于: 2013-08-09
引用第3楼searchcai于2013-08-09 15:29发表的  :
老大熟悉QML吗?
我这边有个触控项目,看你感兴趣不?

你整理下资料,发布到招聘版,肯定会有人做的,呵呵.
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线searchcai

只看该作者 8楼 发表于: 2013-08-09
你中间想退出也可以,那就rollback,比如.

if (db.transaction())
{
   bool bBreak = false;
    while (true)
   {
       if (!db.exec(sql1))
        { bBreak = true;   break;}
       if (!db.exec(sql2))
        { bBreak = true;   break;}
       break;
   }
    if (bBreak)
    {  
         db.rollback();
    }
    else  if ( !db.commit())
    {
         db.rollback();
    }
}

-----------
你得意思我明白了,transaction 必须得和一个commit或一个rollback对应?
那那句代码还是要加的,要不然第一条SQL出了问题return后,没有对应的rollback或commit?
在线XChinux

只看该作者 9楼 发表于: 2013-08-11
今天试验的,MSSQL/QODBC,似乎有些问题,即如果不理会中间的 SQL语句执行对错,而直接commit()的话, commit()总是返回true(即使中间执行的SQL语句有错误),并且已经正确执行的语句会生效. 这就不是我们想要的东西了.

所以现在只能改成这样的逻辑:

if (db.transaction())
{
  bool bBreak =  true;
   while (true)
   {
        if (!q.exec(sql1))  break;
        if (!q.exec(sql2))  break;
         ...
        if (!q.exec(sqln))  break;

        bBreak = false;
        if (!db.commit())
        {
              db.rollback();
        }
        break;
   }
   if (bBreak)
   {
        db.rollback();
   }
}
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线neil-wen

只看该作者 10楼 发表于: 2013-08-14
从中受益,多谢了
快速回复
限100 字节
 
上一个 下一个