Question

I have the following code for a database ( represented by variable db) being used in a hybrid mobile app.

There is no Customers or Items table in SQLite database, so the third and fourth SQL statements throw an error, but still the table Table1Backup ends up being created. Why is this happening since in a transaction an implicit rollback should happen in this case?

db.transaction(function(tx) {
    tx.executeSql("DROP TABLE if exists Table1Backup", [], success, error);
    tx.executeSql("CREATE TABLE if not exists Table1Backup AS 
                                 SELECT * FROM Table1", [], success, error);
    tx.executeSql("CREATE TABLE CustomersBackup AS SELECT * FROM Customers",
                                                    [], success, error);
    tx.executeSql("CREATE TABLE ItemsBackup AS SELECT * FROM Items",
                                                    [], success, error);
   });
}
function success(tx, result) {
      alert("succeeded ");
}
function error(tx, err) {
     alert("ERROR  " + err.message);
}
Was it helpful?

Solution

I found the answer. In order for a transaction to rollback on error, WHEN USING SQLITE IN CORDOVA-BASED HYBRID APP, one must follow ANY one of these options:

  1. If you do provide for error callback, then make sure it returns a true. If the error callback returns a false, then transaction will not rollback and previous statements will auto-commit.

    db.transaction(function(tx) {
    tx.executeSql("DROP TABLE if exists Table1Backup", [], success, error);
    tx.executeSql("CREATE TABLE if not exists Table1Backup AS 
                             SELECT * FROM Table1", [], success, error);
    tx.executeSql("CREATE TABLE CustomersBackup AS SELECT * FROM Customers",
                                                [], success, error);
    tx.executeSql("CREATE TABLE ItemsBackup AS SELECT * FROM Items",
                                                [], success, error);
     });
    }
    function success(tx, result) {
        alert("succeeded ");
    }
    function error(tx, err) {
        alert("ERROR  " + err.message);
        return true;//THIS IS IMPORTANT FOR TRANSACTION TO ROLLBACK ON QUERY ERROR
    }
    
  2. Do not provide an error callback as in code below. You can still provide a success callback if you follow this option.

    db.transaction(function(tx) {
      tx.executeSql("DROP TABLE if exists Table1Backup");
      tx.executeSql("CREATE TABLE if not exists Table1Backup AS SELECT * FROM Table1");
      tx.executeSql("CREATE TABLE CustomersBackup AS SELECT * FROM Customers");
      tx.executeSql("CREATE TABLE ItemsBackup AS SELECT * FROM Items");
     });
    }
    

OTHER TIPS

I perhaps follow below approach, which is much cleaner; also successfully rollbacks the whole transaction

db.transaction(function(tx) {
  tx.executeSql("DROP TABLE if exists Table1Backup");
  tx.executeSql("CREATE TABLE if not exists Table1Backup AS SELECT * FROM " 
    +"Table1");
  tx.executeSql("CREATE TABLE CustomersBackup AS SELECT * FROM Customers");
  tx.executeSql("CREATE TABLE ItemsBackup AS SELECT * FROM Items");
}).then(function(success){
    //do something
}).catch(function(error){
   //transaction gets automatically rolled back
})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top