dexie / Dexie.js

A Minimalistic Wrapper for IndexedDB
https://dexie.org
Apache License 2.0
11.43k stars 641 forks source link

Will it affect the integrity of the data while writing the same dexie.js table at the same time? #601

Open gst-xxz opened 6 years ago

gst-xxz commented 6 years ago

My project is to use the timer and version number to achieve the unification of dexiejs and server database The problem now is that it doesn't go wrong in the case of small concurrency, but when the high point occurs, the statistics are inconsistent

dfahlander commented 6 years ago

Could you explain a little more? I'm having problems understanding what you are trying to achieve.

poltak commented 6 years ago

Also interested in how Dexie handles concurrency, mainly in transactions. Say I have a transaction A that takes maybe 10ms. Then within the window of 1ms of time, transaction A is called 5 times. Does Dexie queue these transactions somehow? I see there is Dexie.currentTransaction prop which is Transaction type rather than an array of them, so that seems to indicate only one can be going on at any time (not counting spawned parallel transactions)?

Had major issues with concurrency like this with other IndexedDB wrapping libs. Some have implemented queues to manage concurrent requests, others we've written queues around the interface to make sure IndexedDB doesn't mess up its data. (though we probably were not using IndexedDB very well)

What did you end up doing for your concurrency issues @xuxiaozhou ?

dfahlander commented 6 years ago

@poltak Dexie [supports parallell transactions](http://dexie.org/docs/Dexie/Dexie.transaction()#parallell-transactions) the same way as IndexedDB does it. Dexie.currentTransaction is a property local to your zone. However, IndexedDB will do table-locking for readwrite-transactions so if you have 5 simultanious readwrite-transactions with same table included, they will in practice affect the DB sequencially. But in case you write to different tables, or they are readonly transactions, they will also execute in parallell.

matte0080 commented 1 year ago

@dfahlander Is transactions safe between multiple tabs? So, i have open a transaction in TAB A and one in TAB B on the same db and table, the second TAB wait for the first transaction on TAB A was finished before to start?

dfahlander commented 1 year ago

@dfahlander Is transactions safe between multiple tabs? So, i have open a transaction in TAB A and one in TAB B on the same db and table, the second TAB wait for the first transaction on TAB A was finished before to start?

Yes, they are safe between tabs and also between windows and workers.

matte0080 commented 1 year ago

@dfahlander Thank you! I have another question. Why my transaction fail always? This is the code.

1) Read all data from table 2) Send data to api endpoint with http angular return observable rxjs, then convert it to Promise and wait until it is resolved; 3) Clear all data from db ( i send all data to api so i need to delete all for not send again this data next cycle time)


db.transaction('rw', db.activity, async () => {
  // 1) Read all data from table
  const data = await db.activity.toArray();
  2) Send data to api endpoint with http angular return observable rxjs, then convert it to Promise and wait until it is resolved;
   await lastValueFrom(this.send(data)); // Wait for promise resolution ( reject if http.post fail otherwise resolve) 
  3) Clear all data from db ( i send all data to api so i need to delete all for not send again this data next cycle time)
  await db.activity.clear();
  })
  .then(() => {
    console.log('Transaction committed');
  })
  .catch((err) => {
    console.error(err.stack);
  });
});

 private send(data: MyClassItems[]) {
    const toSend = {
      version: 1,
      events: data
    };

    return this.http.post(`http://localhost:3000/api/log`, toSend, {
      headers: this.headers
    });
  }

After 2) await lastValueFrom(this.send(data)); // Wait for promise resolution ( reject if http.post fail otherwise resolve) i see transaction active property always false and receive this error:

TransactionInactiveError: Transaction has already completed or failed

Where i wrong?