Re: IndexedDB, what were the issues? How do we stop it from happening again?

On Mon, Mar 18, 2013 at 5:42 PM, Alec Flett <> wrote:
>> transactions - Also should be optional. Vital to complex apps, but totally
>> > not necessary for many.. there should be a default transaction, like
>> > db.objectStore("foo").get("bar")
>> I disagree. This would have made it too trivial to create pages that
>> have race conditions. I.e. people would write code like:
>> db.objectStore("foo").get("bar").onsuccess = function(e) {
>>   db.objectStore("foo").set("bar", + 1)
>> }
>> without realizing that that contains a race condition.
> Its always possible for users to hang themselves - the web platform has lots
> of rope. I could name a dozen gotchas like that in the JavaScript language
> alone. The fact that we introduced shared workers introduces a whole mess of
> issues like that. Not to criticize either - I think its just something that
> happens as you introduce more flexible capabilities into the platform.
> In the above example, you could approach this with automatic transactions -
> all operations that run in the callback of another IDB operation run in the
> same transaction. So the set() and the get() are in the same transaction.

That stops working pretty quickly. If you simply want to add property
'a' to property 'b' you'd get something like:

var a;
db.objectStore("foo").get("a").onsuccess = function(e) {
  a =;
db.objectStore("foo").get("b").onsuccess = function(e) {
  db.objectStore("foo").set("b", + a);

And yes, it's easy to write that code correctly, but I don't think it
passes the following design goal:

 * Make it easy to create pages that are race-free even if opened in
multiple tabs at the same time. Ideally it should be easier to create
a race-free page than a page that has race hazards.

> When you need explicit transactional control then you use the transaction()
> API.

My point is that it's very common to want transactions, even when you
don't think you want to.

I'd much rather spend effort on making it so easy to create
transactions that it's something people don't mind doing, than to
create a transaction-less syntax.

If we enable the use of a "default" objectStore then your example code
would become

var trans = db.transaction();
trans.get("bar").onsuccess = function(e) {
  trans.set("bar", + 1)

And my example code

var a;
trans = db.transaction();
trans.get("a").onsuccess = function(e) {
  a =;
trans.get("b").onsuccess = function(e) {
  trans.set("b", + a);

Which in both cases is just one additional line of code, but fewer
total number of characters typed. I think that's a win compared to
something that will result in more race conditions.

>> > named object stores - frankly, for many use cases, a single objectStore
>> > is
>> > all you need. a simple db.get("foo") would be sufficient. Simply naming
>> > a
>> > "default" isn't bad - whats bad is all the onupgradeneeded scaffolding
>> > required to create the objectstore in the first place.
>> I think we should do this as part of a simple API. Similar to something
>> like
> Yes! I mean that's kind of where this conversation took off... I just don't
> think there should be an obvious distinction between "the API with the
> transactions and versions" and "the one without." - if anything presenting
> them in a unified fashion allows for developers to migrate as they need
> individual features (Transactions, versions, etc)

I definitely agree that it would be cool if indexedDB could have a
smooth transition curve from a simple API up to the full feature set
that it currently has. That's definitely something that I think we
failed on.

But I don't think that requires that we get rid of transactions from
the simple API. And I suspect that that doesn't need to meaningfully
need to make the simple API that much more complicated.

/ Jonas

Received on Tuesday, 19 March 2013 20:53:20 UTC