Interacción inconsistente entre transacciones IndexedDB y Promesas

Yo vipromesa de sincronización publicado en Reddit yentró en una discusión con el autor. Notamos algunas incoherencias extrañas en la relación entre las transacciones y las promesas de IndexedDB.

Las transacciones IndexedDB se confirman automáticamente cuando todas lasonsuccess Eventos terminados. Una complicación es que no puedes hacer nada asincrónico dentro de unonsuccess devolución de llamada excepto hacer otra operación en la misma transacción. Por ejemplo, no puede iniciar una solicitud AJAX en unonsuccess y luego reutilice la misma transacción después de que la solicitud AJAX devuelva algunos datos.

¿Qué tienen que ver las promesas con esto? Según tengo entendido, se supone que la resolución de la promesa siempre debe ser asíncrona. Esto implicaría que no puede usar promesas sin comprometer automáticamente una transacción IndexedDB.

Aquí hay un ejemplo de lo que estoy hablando:

var openRequest = indexedDB.open("library");

openRequest.onupgradeneeded = function() {
  // The database did not previously exist, so create object stores and indexes.
  var db = openRequest.result;
  var store = db.createObjectStore("books", {keyPath: "isbn"});
  var titleIndex = store.createIndex("by_title", "title", {unique: true});
  var authorIndex = store.createIndex("by_author", "author");

  // Populate with initial data.
  store.put({title: "Quarry Memories", author: "Fred", isbn: 123456});
  store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567});
  store.put({title: "Bedrock Nights", author: "Barney", isbn: 345678});
};

function getByTitle(tx, title) {
  return new Promise(function(resolve, reject) {
    var store = tx.objectStore("books");
    var index = store.index("by_title");
    var request = index.get("Bedrock Nights");
    request.onsuccess = function() {
      var matching = request.result;
      if (matching !== undefined) {
        // A match was found.
        resolve(matching);
      } else {
        // No match was found.
        console.log('no match found');
      }
    };
  });
}

openRequest.onsuccess = function() {
  var db = openRequest.result;
  var tx = db.transaction("books", "readonly");
  getByTitle(tx, "Bedrock Nights").then(function(book) {
    console.log('First book', book.isbn, book.title, book.author);
    return getByTitle(tx, "Quarry Memories");
  }).then(function(book) {
    console.log('Second book', book.isbn, book.title, book.author);
    // With native promises this gives the error:
    // InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
    // With bluebird everything is fine
  });
};

(Revelación completa: ¡la demostración fue creada por paldepind, no yo!)

Lo he probado en Chrome y Firefox. Falla en Firefox debido a la transacción de confirmación automática, ¡pero en realidad funciona en Chrome! ¿Qué comportamiento es correcto? Y si el comportamiento de Firefox es correcto, ¿es literalmente imposible usar implementaciones de promesa "correctas" con transacciones IndexedDB?

Otra complicación: si cargoazulejo antes de ejecutar la demostración anterior, funciona tanto en Chrome como en Firefox. ¿Esto implica que bluebird está resolviendo promesas sincrónicamente? ¡Pensé que no se suponía que hiciera eso!

JSFiddle