检查此示例:
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不会回滚回滚机制?
答案 0 :(得分:2)
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。
答案 1 :(得分:0)
到@jyl
当你拨打db.transaction( function( tx ) { ... } )
时,你也可以传递第二个参数error function
,如果发生错误,它将调用它,你不需要返回任何值,交易是自动的中止
我的错误是为每个error function
传递tx.executeSql
,
ie: 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,遗憾的是目前我没有空闲时间来保持更新