fix commit problem in qsql_ibase.cpp

the problem

Transaction with unsuccessful commit can never be rollbacked. This migth cause some metaobjects get locked and as result hanging of any client (including itself) which tries to use that metaobjects. Example:

  1. given the following:
    CREATE SEQUENCE myseq;
     
    CREATE TABLE mytbl (id INTEGER);
     
    CREATE OR ALTER TRIGGER mytrig_bi0 FOR mytbl
    active BEFORE INSERT POSITION 0
    AS
    BEGIN
      NEW.id = NEXT VALUE FOR myseq;
    END
  2. qt code:
      QSqlDatabase db = ...
      QString sql = "drop sequence myseq";
     
      db.transaction();
      QSqlQuery q(sql, db);
      qDebug() << q.lastError().text(); // no error!
      q.close();
      db.commit();
      qDebug() << q.lastError().text(); // error: unsuccessful metadata update...
     
      // trying to drop once more time
      db.transaction();
      QSqlQuery q(sql, db); // blocked forever...

the solution

Edit file …/qtbase/src/sql/drivers/ibase/qsql_ibase.cpp:

bool QIBaseDriver::commitTransaction()
{
    Q_D(QIBaseDriver);
    if (!isOpen() || isOpenError())
        return false;
    if (!d->trans)
        return false;
 
    isc_commit_transaction(d->status, &d->trans);
//    d->trans = 0;
//    return !d->isError(QT_TRANSLATE_NOOP("QIBaseDriver", "Unable to commit transaction"),
//                       QSqlError::TransactionError);
 
    bool res = !d->isError(QT_TRANSLATE_NOOP("QIBaseDriver", "Unable to commit transaction"),
                       QSqlError::TransactionError);
    if( !res )
        isc_rollback_transaction(d->status, &d->trans);
 
    d->trans = 0;
 
    return res;
}

ps

Prefer explicit transation start and commit as shown above because it is not possible to avoid this problem executing queries with implicit transaction control.

dev/qt/qt_ibase_fix_commit.txt · Последние изменения: 2015/05/20 14:41 — denis
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0