7

正如Safari 客户端存储和离线应用程序编程指南中所写,回滚 HTML 5 Web SQL 数据库事务是通过在作为事务错误回调方法提供的回调函数中返回 true 来完成的executeSql

每个查询的错误处理回调相当简单。如果回调返回 true,则整个事务将回滚。如果回调返回 false,则事务继续进行,就好像没有出错一样。因此,如果您正在执行一个可选的查询——如果该特定查询的失败不应导致事务失败——您应该传入一个返回 false 的回调。如果查询失败导致整个事务失败,则应传入一个返回 true 的回调。

例如,如果我有以下事务(假设 'users' 表在 'username' 字段上有一个 UNIQUE 约束并且用户名 'test' 已经存在 - 我正在尝试再次插入,这将导致约束错误) :

database.transaction(function(transaction) {
    transaction.executeSql(
        "INSERT INTO users (username) VALUES('test')",
        null,
        dataCallback,
        errorCallback
     );
});

function errorCallback() {
    return true; //this causes the rollback
}

我有两个问题:

  1. 如果我必须在事务中包含许多操作(例如,我必须使用 ajax 将一些数据发送到服务器并等待响应等)并且用户在响应到达之前重新加载页面(这意味着 errorCallback不会被调用),事务会被提交还是会失败?

  2. 有谁知道如何手动回滚 Web SQL 事务?例如,如果我想根据 ajax 调用的结果回滚事务,该怎么做?我应该运行包含错误的查询以确保调用错误回调吗?

谢谢。

4

2 回答 2

2
  1. 事务将被提交。
  2. 是的,要显式回滚,您必须显式调用无效查询。这是推荐的解决方法,因为快速和肮脏的 API 缺少abort方法。

关于 AJAX,在开始写事务之前准备好所有数据。正如你所描述的,你不会有任何问题。尽可能使用数据库约束(UNIQUE、FOREIGNKEY)。

于 2013-04-05T02:52:50.147 回答
1

您是否找到了在事务期间进行 AJAX 调用的方法?我还没有读完整个规范,但到目前为止,看起来一旦你的SQLTransactionCallbackorSQLTransactionSyncCallback返回,你就不能再向交易添加任何东西了——或者你可以吗?也许来自结果回调?

编辑:现在我再看一遍,规范(其中包含的错误比您链接到的 Apple 文档少得多,但不那么容易阅读)

  1. 如果在执行,executeSql期间未调用方法 [ ] ,则引发异常。SQLTransactionCallbackSQLStatementCallbackSQLStatementErrorCallbackINVALID_STATE_ERR

所以我认为这意味着没有办法做到这一点。

进一步编辑:不,等等!只要调用SQLStatementCallback需要一些时间,您就可以一遍又一遍地忙着等待select 3 + 4,每次从 previous 的语句回调开始select 3 + 4,直到您的 AJAX 调用在某处设置一个包含您想要的数据的标志。这是一种糟糕的编程(它会无缘无故地消耗大量 CPU,可能会阻止低优先级任务,例如重新显示页面),但我认为这可能是在任意时间段内保持事务打开的唯一方法。太糟糕了,你不能select 3 + 4, sleep(1)在 SQLite 中。

一般来说,SQLite(这里的底层存储引擎)会回滚未完成的事务。我尚未测试您询问的页面重新加载错误案例。如果它被承诺,我会感到非常惊讶。

顺便说一句,非常感谢您发布这个问题。我一直在试图弄清楚如何让事务回滚,即使在原始规范中有详细记录。

于 2011-03-16T21:13:30.047 回答