The interaction between transactions and objects that allow multiple operations 
is giving us trouble. I need to elaborate a little to explain the problem.

You can perform operations in IndexedDB with or without an explicitly started 
transaction. When no transaction is present, you get an implicit one that is 
there for the duration of the operation and is committed and the end (or 
rolled-back if an error occurs).

There are a number of operations in IndexedDB that are a single step. For 
example, store.put() occurs either entirely in the current transaction (if the 
user started one explicitly) or in an implicit transaction if there isn't one 
active at the time the operation starts. The interaction between the operation 
and transactions is straightforward in this case.

On the other hand, other operations in IndexedDB return an object that then 
allows multiple operations on it. For example, when you open a cursor over a 
store, you can then move to the next row, update a row, delete a row, etc. The 
question is, what is the interaction between these operations and transactions? 
Are all interactions with a given cursor supposed to happen within the 
transaction that was active (implicit or explicit) when the cursor was opened? 
Or should each interaction happen in its own transaction (unless there is a 
long-lived active transaction, of course)?

We have a few options:
a) make multi-step objects bound to the transaction that was present when the 
object is first created (or an implicit one if none was present). This requires 
new APIs to mark cursors and such as "done" so implicit transactions can 
commit/abort, and has issues around use of the database object while a cursor 
with an implicit transaction is open.

b) make each interaction happen in its own transaction (explicit or implicit). 
This is quite unusual and means you'll get inconsistent reads from row to row 
while scanning unless you wrap cursor/index scans on transactions. It also 
probably poses interesting implementation challenges depending on what you're 
using as your storage engine.

c) require an explicit transaction always, along the lines Nikunj's original 
proposal had it. We would move most methods from database to transaction 
(except a few properties such as version and such, which it may still be ok to 
handle implicitly from the transactions perspective). This eliminates this 
whole problem altogether at the cost of an extra step required always.

We would prefer to go with option c) and always require explicit transactions. 


Reply via email to