【问题标题】:HTML 5 Web SQL Database Transaction commit or rollback when refreshing page刷新页面时 HTML 5 Web SQL 数据库事务提交或回滚
【发布时间】:2011-07-05 19:20:11
【问题描述】:

Safari Client-Side Storage and Offline Applications Programming Guide 中所写,回滚 HTML 5 Web SQL 数据库事务是通过在作为错误回调提供给 executeSql 方法的 事务 的回调函数中返回 true 来完成的:

每个查询的错误处理回调 相当简单。如果 回调返回true,整个 事务被回滚。如果 回调返回 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 调用的结果回滚事务,该怎么做?我应该运行包含错误的查询以确保调用错误回调吗?

谢谢。

【问题讨论】:

    标签: javascript database html transactions web-sql


    【解决方案1】:
    1. 事务将被提交。
    2. 是的,要显式回滚,您必须显式调用无效查询。这是推荐的解决方法,因为 quick-and-dirty API 缺少 abort 方法。

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

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

      【讨论】:

      • 我尝试在 AJAX 调用之前将事务对象保存到一个变量中,并在它返回后使用它来执行另一个查询。但是我得到一个 DOM 异常,指出不能再使用事务对象。这仅发生在 AJAX 调用之后,使用同步函数/回调我可以将其作为参数传递并在单个事务中运行多个查询。我还没有尝试过同步调用 AJAX(例如使用 jQuery),也许这会使事务对象保持在有效状态。
      • 查看我上面关于保持交易开放的编辑。我不认为 jQuery 支持同步 AJAX;它会冻结页面和(在 Chrome 之外)整个浏览器,直到完成。
      • 这是在事务期间执行 AJAX 或任何超时调用的方法:linkedin.com/pulse/…
      猜你喜欢
      • 1970-01-01
      • 2019-04-09
      • 2018-01-02
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多