title: IndexedDB transaction.oncomplete with multiple actions
body: <p>The question is: how does an IDBTransaction -- the kind you get from IDBDatabase, we'll call it type A -- know when to call <code>oncomplete</code> if it can be include an arbitrary number of IDBTransaction (type B) children?</p>
  
  <p>First, you get your 'type A' IDBTransaction from the database connection:</p>
  
  <pre><code>const transA = IDBDatabase.transaction(storeName, mode);
  </code></pre>
  
  <p>This IDBT may carry the <code>oncomplete</code> event, and supposedly it will fire when the <em>total</em> transaction is complete. But you use this IDBT to 'launch' the real transactions via one or more retrieved IDBObjectStores:</p>
  
  <pre><code>const store = transA.objectStore(storeName);
  const transB1 = store.delete(key);
  const transB2 = store.add(item);
  </code></pre>
  
  <p>Now, <code>transB1</code> and <code>transB2</code> are also instances of IDBTransaction, which may have their own <code>oncomplete</code> handlers. The idea of the parent transaction here, as I understand it, is that it permits the aggregate transaction to be atomic; if transB1 succeeds but transB2 fails, transB1 is rolled back. Good. So we'll generally be more interested in listening to the parent, not the children, since this is what tells us if it <em>really</em> succeeded.</p>
  
  <p>The catch I don't get: there's no <code>close</code> or <code>done</code> or <code>finish</code> method or whatever. So how does <code>transA</code> actually know when to trigger <code>oncomplete</code>?</p>
  
  <p>All I can think of at the moment is that it expects all child transactions to be created during a single tick. Is that what's going on? (It's already pretty apparent that IndexedDB is painfully un-JS, but quietly relying on synchrony to imply behavior like that seems like a boundary even the DOM overlords would not cross.) What's really going on?</p>