Skip to content

Support multiple operations per transaction, with Treo sugar #32

Description

@glsignal

Currently (as I understand it), Treo opens a transaction for each atomic operation—get, put etc.—allowing for the possibility of data changes between read and write:

var facts = db.store('avocadoFacts');

facts.get(12).then( (realAvocadoFact) =>  {
  // If I wanted to update that record here, that happens in a new transaction. It's possible that some change happens to the record in IndexedDB while I'm playing with it in memory.
  realAvocadoFact.body = "sometimes avocados have bad taste";
  facts.put(realAvocadoFact, () => {
    /* My changes are done and persisted */
  });
});

While it's probably not a huge deal for many applications, I'm running into it fairly frequently (my data is not directly generated by a user interface) and so I'm finding myself falling back to IndexedDB's standard API; opening a big transaction to do my work, and hence losing a lot of the Treo sugar.

(I'll note that I'm working in a chrome extension too, so there are multiple JS environments executing at any given time, all with access to the same IndexedDB stores).

db.transaction("readwrite", ["avocadoFacts"], (err, tx) => {
  var facts = tx.objectStore("avocadoFacts");

  facts.get(12).onsuccess = (evt) => {
    var realAvocadoFact = evt.target.result; 
    realAvocadoFact.body = "sometimes avocados have bad taste";
    facts.put(realAvocadoFact);
  };

  tx.oncomplete = () => {
    /* My changes are done and persisted */
  };
});

I was wondering if there were any plans for a feature like chaining reads and writes together in a single transaction (effectively making an update call that's much less verbose than the IndexedDB equivalent), or any thoughts on how difficult it might be to carry over the transaction to arbitrary actions on data.

This is a little hairy and ill-defined, but for instance here's some code I'd like to be able to write:

var facts = db.store('avocadoFacts');

facts.openTransaction()
  .get(12)
  .put( (realAvocadoFact) =>  {
    realAvocadoFact.body = "sometimes avocados have bad taste";
    return realAvocadoFact; // return value is persisted and passed to any chained functions
  })
  .done( (realAvocadoFact) => {
    /* My changes are done and persisted */
  });
});

Terrible API aside (very little thought has gone into it; I just want to open the discussion), is it clear what I'm getting at? The example above (updating a record) might be better as a plugin's job, but I'd be interested to hear your thoughts on making better use of transactions in situations like these, and addressing the root cause. Transactions as a concept are extremely useful, but I feel like they're being under utilised.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions