Cordova SQLite交易没有回滚

时间:2014-03-09 20:50:32

标签: sqlite cordova hybrid-mobile-app

我在混合移动应用程序中使用的数据库(由变量db表示)有以下代码。

SQLite数据库中没有Customers或Items表,因此第三个和第四个SQL语句会抛出错误,但最终仍会创建表Table1Backup。 为什么会发生这种情况,因为在事务中,在这种情况下会发生隐式回滚?

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);
}

2 个答案:

答案 0 :(得分:4)

我找到了答案。为了使事务在出错时回滚,在基于CORDOVA的HYBRID APP中使用SQLITE时,必须遵循以下任何一个选项

  1. 如果确实提供了错误回调,那么请确保它返回true。如果错误回调返回false,则事务将不会回滚,之前的语句将自动提交。

    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. 不提供错误回调,如下面的代码所示。如果您按照此选项仍然可以提供成功回调。

    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");
     });
    }
    

答案 1 :(得分:1)

我也许遵循以下方法,这更加清洁;也成功回滚了整个交易

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
})