Seite 1 von 1
QSqlDatabase::transaction()
Verfasst: 24. April 2009 17:43
von Marco812
Hi,
wie kann man eine Transaction bei Fehlern rückgängig machen?
Beispiel:
Code: Alles auswählen
QSqlDatabase db = QSqlDatabase::database();
db.transaction();
QSqlQuery q;
for (int i=0; i<5; i++)
{
q.exec("DELETE FROM user WHERE user_id ="+ QString().setNum(i) +";");
}
q.clear();
if(!db.commit()){
db.rollback();
}
Wenn es jetzt einen Fehler gibt, sollte db.commit() != true sein und db.rollback() ausgeführt werden, was aber nicht der Fall ist. Hat jemand eine Lösung bzw. Erklärung dafür?
Verfasst: 24. April 2009 19:40
von upsala
Welche Datenbank? Werden von der Datenbank auch Transaktionen unterstützt?
Verfasst: 24. April 2009 23:55
von Marco812
Das ist eine SQLite-Datenbank.
Transaktionen sollten unterstützt werden, da db.rollback() funktioniert, wenn ich absichtlich einen Fehler produziere und anschließend das rollback durchführe. Mir ist aber nicht klar, warum ich bei if(!db.commit()) den Wert TRUE erhalte, wenn zuvor eine oder mehrere fehlerhafte QSqlQuery's ausgeführt wurden.
Hat jemand eine Erklärung dafür?
Verfasst: 25. April 2009 09:13
von upsala
Ich weis nicht, wie es bei SQLite ist, aber bei anderen Datenbanken kenn ich es so, das nach einem fehlgeschlagenen COMMIT kein ROLLBACK notwendig ist, da dies automatisch ausgeführt wird.
Verfasst: 25. April 2009 09:21
von franzf
hier steht bissl was
http://www.sqlite.org/lang_transaction.html
u.a. das hier:
But a transaction will also ROLLBACK if the database is closed or if an error occurs and the ROLLBACK conflict resolution algorithm is specified.
muss man nur noch wissen, ob qt von sich aus einen "conflict resolution algorithm" setzt.
Verfasst: 27. April 2009 10:59
von Marco812
Also bei einem COMMIT wird nach einem Fehler nicht automatisch ein ROLLBACK durchgeführt.
Wie bereits erwähnt, das ROLLBACK funktioniert, sobald ich es nach einem Fehler per Hand ausführe.
Mir ist aber immer noch nicht klar warum nach einem Fehler in einer QSqlQuery COMMIT == TRUE ist. Wie kann ich außer mit COMMIT prüfen ob ein ROLLBACK notwendig ist?
Verfasst: 27. April 2009 17:43
von Marco812
Nach langem lesen in der Dokumentation habe ich folgendes versucht:
Code: Alles auswählen
QSqlDatabase db = QSqlDatabase::database();
QSqlQuery q(db);
qDebug() << db.driver()->hasFeature(QSqlDriver::Transactions); //true
Demzufolge werden Transaktionen unterstützt. Worauf ich folgendes versucht habe:
Code: Alles auswählen
qDebug() << db.driver()->beginTransaction(); //true
qDebug() << q.exec("SELECT;"); //false
qDebug() << db.driver()->commitTransaction();//true
und
Code: Alles auswählen
qDebug() << q.exec("BEGIN TRANSACTION"); //true
qDebug() << q.exec("SELECT;"); //false
qDebug() << q.exec("COMMIT");//true
Ich verstehe nicht warum immer COMMIT == TRUE ergibt, obwohl ein Fehler erzeugt wurde, was durch q.lastError() auch bestätigt wird. Was mache ich falsch?
Kann mit jemand sagen wie ich ein "conflict resolution algorithm" setzen kann, was das überhaupt ist und ob es ggf. bereits von Qt gesetzt wird?
Verfasst: 1. Oktober 2009 17:08
von ms47
Marco812 hat geschrieben:Nach langem lesen in der Dokumentation habe ich folgendes versucht:
Code: Alles auswählen
QSqlDatabase db = QSqlDatabase::database();
QSqlQuery q(db);
qDebug() << db.driver()->hasFeature(QSqlDriver::Transactions); //true
Demzufolge werden Transaktionen unterstützt. Worauf ich folgendes versucht habe:
Code: Alles auswählen
qDebug() << db.driver()->beginTransaction(); //true
qDebug() << q.exec("SELECT;"); //false
qDebug() << db.driver()->commitTransaction();//true
und
Code: Alles auswählen
qDebug() << q.exec("BEGIN TRANSACTION"); //true
qDebug() << q.exec("SELECT;"); //false
qDebug() << q.exec("COMMIT");//true
Ich verstehe nicht warum immer COMMIT == TRUE ergibt, obwohl ein Fehler erzeugt wurde, was durch q.lastError() auch bestätigt wird. Was mache ich falsch?
Kann mit jemand sagen wie ich ein "conflict resolution algorithm" setzen kann, was das überhaupt ist und ob es ggf. bereits von Qt gesetzt wird?
Hallo,
habe zurzeit das gleiche Problem und wollte mal fragen, ob du diesbezüglich weiter gekommen bist?
Danke und Gruß
Markus
Verfasst: 1. Oktober 2009 17:30
von upsala
Wie lautet eigentlich die Fehlermeldung, die lastError() zurückliefert?
Verfasst: 1. Oktober 2009 17:37
von ms47
upsala hat geschrieben:Wie lautet eigentlich die Fehlermeldung, die lastError() zurückliefert?
Bei mir ist es:
Code: Alles auswählen
QSqlError(-1, "QPSQL: Unable to create query", "FEHLER: Spalte »is_value« hat Typ boolean, aber der Ausdruck hat Typ integer
Verfasst: 1. Oktober 2009 20:42
von upsala
Ok, commitTransaction liefert nur dann einen (Transaktionsfehler) wenn das Kommando selbst schief geht.
Aber: Wenn eine Query schon false liefert, sollte hier schon die Transaktion abgebrochen werden.
Auf der anderen Seite kann man event. aber hier ein wenig tricksen:
select //false
...
select 1 //jetzt ebenfalls false, da oben schon false
commit //