[whatwg] Database feedback
Jonas Sicking
jonas at sicking.cc
Wed Nov 26 11:31:31 PST 2008
Ian Hickson wrote:
> 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?
I'm fine with either the perf-hit solution or the
.writeTransaction/.readTransaction solution. Both seems better than
having writes throw under basically race conditions. If we go with the
perf-hit solution we can always add the speedier
.writeTransaction/.readTransaction APIs in a later version.
/ Jonas
More information about the whatwg
mailing list