-
-
Notifications
You must be signed in to change notification settings - Fork 664
Dexie.PrematureCommitError
Since 2.0.0
-
Error
-
Dexie.DexieError
- Dexie.PrematureCommitError
-
Dexie.DexieError
This exception will be thrown when the indexedDB transaction commits before the promise returned by your transaction scope is resolved or rejected.
- Make sure to never call other async APIs from within a transaction
- Always use the global Promise (or Dexie.Promise) inside transactions.
db.transaction ('rw', db.friends, () => {
return fetch(someUrl); // fetch() is a non-indexedDB async API.
});
db.transaction ('rw', db.friends, () => {
return new Promise (resolve => {
setTimeout(resolve, 100); // setTimeout is non-indexedDB async API.
});
});
Dont call setTimeout() or any other async API from inside a transaction.
let Promise = require('bluebird');
db.transaction('r', db.friends, () => {
return new Promise((resolve, reject) => {
db.friends.get(1).then(resolve, reject);
});
});
Don't use 3-rd part promises within transactions. Must only use Dexie.Promise or the built-in promise (window.Promise / self.Promise / global.Promise) within transactions.
db.transaction('r', db.friends, function () {
// In Dexie 2.0, it's ok to use the global Promise (Promise.all() in this case)
return Promise.all([
db.friends.get(1),
db.friends.get(2)
]);
});
db.transaction('r', db.friends, async () => {
// In Dexie 2.0, it's ok to use the global Promise (Promise.all() in this case)
return await Promise.all([
db.friends.get(1),
db.friends.get(2)
]);
});
Since Dexie 2.0, you may use the global Promise within transactions, since it will always be temporary patched within the transaction zone. But interactions with non-Dexie API:s must only be done outside transactions. For example if you need to fetch data from a REST API, do that before entering the transaction. And if you need to call REST API based on a database query, do that when your transaction completes.
async function sample() {
let restData = await fetch(someUrl);
let dbResult = await db.transaction('rw', db.someTable, async ()=> {
let changedItems = await db.someTable
.where('changeDate').above(lastSyncDate)
.toArray();
await db.someTable.bulkPut(restData);
return changedItems;
});
await fetch(someUrl, {method: 'POST', body: dbResult});
}
In this trivial sync-sample, the fetch() API is only called from outside the transaction.
Dexie.js - minimalistic and bullet proof indexedDB library