- From: Ian Hickson <ian@hixie.ch>
- Date: Wed, 26 Nov 2008 11:46:52 +0000 (UTC)
There's a question at the bottom about how best to make transactions be free of concurrency problems. Input welcome. On Fri, 23 May 2008, Aaron Boodman wrote: > > I noticed one unfortunate thing about the new Database API. Because the > executeSql() callback holds open the transaction, it is easy to > accidentally do intensive work inside there and hold open the > transaction too long. A common mistake might be to do a big select and > then hold open the transaction while the UI is updated. This could hold > open the tx maybe an extra couple hundred ms. A bigger problem would be > to do synchronous XHR (for example, in workers). This could hold open > the tx for seconds. > > The right place to do work like this is in transaction()'s success > callback. But because the resultsets aren't easily accessible there, I > think authors are more likely to do work in executeSql()'s success > callback and use transaction()'s success callback less frequently. > > Off hand about the best solution I can think of to this problem is to > have some sort of state on the transaction object that gathers the > results. > > This is not very satisfying though. Does anyone have a better idea? Or > think this is not a big enough concern to worry about? I agree that this might be a problem. I'm not sure how to address it. On Tue, 27 May 2008, Scott Hess wrote: > > I think the only way you can really make it better is to put something > like an executeSql() function directly on Database objects, which could > shift the success callback entirely outside the transaction scope. I > think that would reasonably match server-side SQL use (you either send a > bare SELECT with implicit transaction, or use explicit BEGIN/END to > group things which must be consistent). I don't want to add this yet, in case it turns out we don't really need it, but implementation experience will definitely tell us whether this is needed or not and if it is we will have to add it in v2. On Mon, 26 May 2008, Aaron Boodman wrote: > > Quick thing. I don't think the spec makes it clear whether it is allowed > to do this: > > var db1 = window.openDatabase("foo", "", "", ""); > var db2 = window.openDatabase("foo", "1", "", ""); > > I think the answer should be "no". Thoughts? > > If so, perhaps edit this sentence: > > If the database version provided is not the empty string, and the > database already exists but has a different version, then the method > must raise an INVALID_STATE_ERR exception. > > To read like this: > > If the database version provided is not the empty string, and the > database already exists but has a different version, or no version, then > the method must raise an INVALID_STATE_ERR exception. Fixed. On Mon, 26 May 2008, Chris Prince wrote: > > I think the spec is technically correct. What's confusing is that the > same line can mean two different things: > > // Start with no databases. > > // On the 1st call, this line means "create a database, > // and set the version string to the empty string". > var db1 = window.openDatabase("foo", "", "", ""); > > // On the 2nd call, the meaning has changed to > // "open the 'foo' database, regardless of the version string". > var db2 = window.openDatabase("foo", "", "", ""); Yeah, that's a bit confusing. Not sure what to do about it. On Mon, 4 Aug 2008, Aaron Boodman wrote: > > It seems like you need a way to abort an in-progress transaction. An > easy way to do this would be to add an abort() method to SQLTransaction. What's the use case? Can we wait until v2 to add this, or is it critical? On Mon, 4 Aug 2008, Aaron Boodman wrote: > > Currently, the database API has an error code for the situation where > you open a transaction for read, then try to write but the database is > locked. > > I think that the spec should at least suggest, but perhaps require, > implementors to serialize access to a single database to prevent this > from happening. Without this, developers must wrap every single write > attempt in error handling and retry if a lock error occurs. > > It seems likely that developers will forget to do this and it will be a > significant pain point with the API. Applications will seem to work, but > then mysteriously fail in production when users have multiple copies of > the application open. > > Even if the developer adds retry logic, it is easy for a page to get > starved by another page. > > Serializing access would prevent all these problems at the cost of read > concurrency, which I think is OK for the first version of this API. A > future version of the API could add the concept of "read transactions" > which would allow concurrency, but would fail immediately when you try > to write with them. I am loath to do this, because of the performance hit. However, what we could do is say that if the first statement is read-only, they all have to be, and if the first statement is a write, then it locks the database? Though that would be rather weird... We could have a .writeTransaction() and a .readTransaction(), where the former always run in isolation. Any preferences? -- Ian Hickson U+1047E )\._.,--....,'``. fL http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Received on Wednesday, 26 November 2008 03:46:52 UTC