3

检查这个例子:

var db = openDatabase( 'test.db', 1, '', 2*1024*1024 );

db.transaction(function(tx) { 
    var success = function(tx,results) {
        console.log( results );
    };
    var error = function(tx,results) {
        console.log( results );
    };
    // clean previous state
    tx.executeSql( 'DROP TABLE IF EXISTS products', [], success, error );
    tx.executeSql( 'CREATE TABLE products ( id INTEGER NULL PRIMARY KEY, name TEXT )', [], success, error );
    tx.executeSql( 'CREATE UNIQUE INDEX name ON products( name )', [], success, error );
    tx.executeSql( 'INSERT INTO products( name ) VALUES ( "Lechuga" )', [], success, error );
    tx.executeSql( 'INSERT INTO products( name ) VALUES ( "Naranja" )', [], success, error );
    tx.executeSql( 'INSERT INTO products( name ) VALUES ( "Naranja" )', [], success, error );
    tx.executeSql( 'INSERT INTO products( name ) VALUES ( "Tomate" )', [], getAll, error );
} );

function getAll(tx, results) {
    db.transaction(function(tx) {
        tx.executeSql( 'SELECT * FROM products', [], function(tx, results) {
            console.assert( results.rows.length === 0 ) // false, why?
        } );
    } );
}

jsfiddle 链接:http: //jsfiddle.net/aBx7E/6/

触发唯一约束的插入查询,不要停下来让 websql 继续执行下一个查询。因此,在流程结束时,您将有 4 行,这是没有意义的,因为如果我处于事务状态,当触发约束错误时,表上的所有先前更改都将被丢弃。

为什么Websql不触发回滚机制?

4

2 回答 2

3

WebSQL 事务中的错误处理程序需要为要中止的事务返回一个非假值。在这种情况下,错误处理程序只调用console.log,这实质上允许事务继续进行。

如果你把它作为错误处理程序:

var error = function(tx,results) {
    console.log( results );
    return true; // added a non-false return value
};

然后,当违反唯一性约束时,事务应该按预期中止。

(我敢肯定你现在已经想通了,但是我遇到了同样的问题,看到了这个问题,没有得到答案,不得不自己想办法。)

编辑:由于我没有评论权限,这在http://www.w3.org/TR/webdatabase/#processing-model第 6 步中进行了概述。我不需要手动回滚任何查询或更改我的查询语句到目前为止已正确中止事务。可能存在实现差异,因为我一直在桌面 Safari 上使用 Web SQL。

于 2014-02-24T16:18:32.873 回答
0

给@jyl

当您调用时db.transaction( function( tx ) { ... } ),您还可以传递第二个参数 an error function,如果发生错误,它将调用它,您不需要返回任何值,事务会自动中止

我的错误是传递一个error functionfor each tx.executeSqlie: tx.executeSql( 'INSERT INTO products( name ) VALUES ( "Naranja" )', [], success, error ) 而不是db.transaction函数,这是监听失败事务的正确位置

还有一件事,最重要的是,当事务失败时,sqlite3 不会回滚以前通过 INSERT、UPDATE 或 DELETE 子句所做的任何更改,解决方案是通过添加OR ROLLBACK关键字来构建您的查询,即:INSERT OR ROLLBACK ta ta...

我有一个适用于 IndexedDB 和 WebSQL 实现的 ORM 库,为您提供一个通用 api:https ://github.com/arcollector/msqta.orm ,遗憾的是目前我没有空闲时间来更新它

于 2014-02-25T02:25:31.297 回答