Problem / bug in Chrome with Web SQL when running many queries?
It seems that when one runs a lot of consecutive SQL queries in Chrome, some get "lost", ie they don't terminate but don't trigger any kind of error / warning.
Here is the simplest test I could come up with:
var shortName = "db", version = "1.0", displayName = "db", maxSize = 20 * 1024 * 1024;
var db = openDatabase(shortName, version, displayName, maxSize);
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS cache (key TEXT PRIMARY KEY ASC NOT NULL, value TEXT NULL);");
});
for (var i=0; i<5; i++) {
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM cache WHERE key = ?", ["test"],
function() {
console.log("ok");
},
function() {
console.warn("error: ", err);
});
});
}
Now if I put the above code in a webpage, I expect to see FIVE "ok" in the console, like so: http://i.stack.imgur.com/FgcNz.png (this is correct).
But if I reload the page fast, I sometimes get an inferior number, with no error or warning of any kind, like this for example: http://i.stack.imgur.com/bc5Kl.png (this is i开发者_C百科ncorrect: only TWO "ok" instead of five).
Here are my questions:
- is there an error in the code above?
- if not, is this a Chrome/Sqlite bug or "normal"/expected behavior?
- and most importantly, how can I code defensively against this? I really need to know whether each query terminates, because if they can just end in limbo then the part of the code that depend on it is never run...
I use 9.0.597.19 beta.
I have the same problem. Code that runs fine on Safari and Opera shows unexpected, but reproducible, results in Chrome (latest production version: 8.0.552.237).
I'm trying to (pre)populate a database with a 1000+ rows retrieved via XMLHTTPRequests. For tables with about 20 rows everyting works fine. Two tables, however have (or should have) 147 and 857 rows respectively. Populating them "stops" after 7 records.
A hunch of an explanation for the number "7" is that the last table that does work correctly has seven records. After that, somehow, things start screwing up...
Putting "failure" callbacks in place to log stuff to the console does not yield any info.
I'm not quite sure why you would only get two "ok" and no errors, but you are likely to see intermittent problems with your code because db.transaction is asynchronous. Meaning that your code doesn't wait for the create table transaction to complete before it executes the rest of the code in your script, so it can possibly start running queries against a table that's still being initialized. To play it safe, use a callback:
var shortName = "db", version = "1.0", displayName = "db", maxSize = 20 * 1024 * 1024;
var db = openDatabase(shortName, version, displayName, maxSize);
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS cache (key TEXT PRIMARY KEY ASC NOT NULL, value TEXT NULL);");
}, [], onTableInitialized);
function onTableInitialized() {
for (var i=0; i<5; i++) {
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM cache WHERE key = ?", ["test"],
function() {
console.log("ok");
},
function() {
console.warn("error: ", err);
});
});
}
}
The 5 queries could all be running at once and could finish in a different order than they started, but that should be fine.
You need to create one db.transaction and in for() create many tx.executeSql
db.transaction(function (tx) {
for (var i=0; i<5; i++)
{
tx.executeSql("SELECT * FROM cache WHERE key = ?", ["test"],
function() {
console.log("ok");
},
function() {
console.warn("error: ", err);
});
}
});
精彩评论