- From: Jeremy Orlow <jorlow@chromium.org>
- Date: Wed, 4 Aug 2010 16:42:50 +0100
- To: public-webapps WG <public-webapps@w3.org>
- Message-ID: <AANLkTinaGgUuv1TX4NpOcvzqrH7JpAAF1e4-J5m0onTH@mail.gmail.com>
In the IndexedDB spec, there are two ways to create a transaction. One is explicit (by calling IDBDatabase.transaction()) and one is implicit (for example, by calling IDBDatabase.objectStore.get("someKey")). I have questions about the latter, but before bringing these up, I think it might be best to give a bit of background (as I understand it) to make sure we're all on the same page: *Belief 1:* No matter how the transaction is started, any subsequent calls done within an IDBTransactionEvent (which is the event fired for almost every IDBRequest.onsuccess call since almost all of them are for operations done within the context of a transaction) will continue running in the same transaction. So, for example, the following code will atomically increment a counter: myDB.transaction().onsuccess(function() { myDB.objectStore("someObjectStore").get("counter").onsuccess(function() { myDB.objectStore("someObjectStore").put("counter", event.result + 1); }); }); *Belief 2:* Let's say I ran the following code: myDB.transaction().onsuccess(function() { window.myObjectStore = myDB.objectStore("someObjectStore"); /* do some other work */ }); And then at any point later in the program (after that first transaction had committed) I could do the following: myDB.transaction().onsuccess(function() { window.myObjectStore.get("some value").onsuccess(...); }); Even though myObjectStore was originally fetched during some other transaction, it's quite clear that I'm accessing values from that object store in this new transaction's context, and thus that's exactly what happens and this is allowed. *Implicitly created transactions:* At a high level, the intent is for IDBDatabase.objectStore.get("someKey").onsuccess(...); to "just work", even when not called in an IDBTransactionEvent handler. But what happens if I run the following code (outside of an IDBTransactionEvent handler): for (var i=0; i<5; ++i) myDB.objectStore("someObjectStore").get("someKey").onsuccess(...); Do we want that to create 5 separate transactions or 5 requests within the same transaction? And what if we run my earlier example (that stored an object store to window.myObjectStore within a transaction we started explicitly) and then run the following code (outside of an IDBTransactionEventHandler): window.myObjectStore.get("someKey").onsuccess(...); myDB.objectStore("someObjectStore").get("someKey").onsuccess(...) Should both be legal? Will this create one or two transactions? *Speccing such transactions:* After thinking about this, I only see a couple options for how to spec implicitly created transactions: "When an operation that needs to be done in a transaction (i.e. anything that touches data) is done outside of an IDBTransactionEvent handler..." 1) "that operation will be done in its own, newly created transaction." 2) "if there already exists an implicitly created transaction for that objectStore, it'll be done in that transaction. Otherwise a new one will be created." 3) "if there already exists _any_ transaction with access to that objectStore, it'll be done in that transaction. Otherwise a new one will be created." 2 seems like it'd match the users intention in a lot of cases, but its biggest problem is that it's non-deterministic. If you do one .get() and then set a time out and do another, you don't know whether they'll be in the same transaction or not. 3 seems to have the same problem except it's even less predictable. So, but process of elimination, it seems as though 1 is our only option in terms of how to spec this. Or am I missing something? *Read-only by default too?* Another somewhat related question: should implicitly created transactions be read-only (which is the default for explicitly created ones)? If so, that means that we expect the following to fail: myDB.objectStore("someObjectStore").get("counter").onsuccess(function() { myDB.objectStore("someObjectStore").put("counter", event.result + 1); }); Unfortunately, it seems as though a lot of use cases for implicitly created transactions would involve more than just reads. But if we spec that to succeed, then we're lowering concurrency and making things inconsistent with the default for IDBDatabase.transaction(), right? *Conclusion:* Am I missing something here? Or will properly speccing implicitly created transactions lead to them being nearly useless for the simple use cases we were trying to make simpler to begin with? J
Received on Wednesday, 4 August 2010 15:43:42 UTC