Replies: 8 comments
-
@alextekartik can you please give it a look when you have some time |
Beta Was this translation helpful? Give feedback.
-
My experiments with isolate are very limited but this looks fine to me and I took a similar approach in the past. I think I decided to open with I understand testing is complex here (I was mainly using print for debugging in theses cases). Does it work fine so far and are you having any issue with your solution ? |
Beta Was this translation helpful? Give feedback.
-
Thanks for the answer. Do you know what can be the scenarios in which the version will get updated without running the full upgrade, this needs to be investigated since it is a very risky behavior, the upgrade happens in a transaction the full transaction should have completed or rolled back including version update. Well it's in the planning phase, haven't rolled out yet, however I added another check to know whether DB exists or not, which should be run before checking DB version using openReadOnlyDatabase, since this will throw if DB does not exist |
Beta Was this translation helpful? Give feedback.
-
Ah yes that was the original issue you reported, sorry. As you mentioned since the whole upgrade process run in a transaction this cannot happen. |
Beta Was this translation helpful? Give feedback.
-
I need to understand this part, why should it be a problem, since in other Isolate as well first the upgrade will run, there also is a transaction which should have atomicity committing at the end, which means even if other Isolate tried to update the DB, shouldn't that also either fully commit or rollback the upgrade.
Here is the pseudo code of the methods you mentioned:
|
Beta Was this translation helpful? Give feedback.
-
Well it is a bit more complicated as statements are not ran in the isolate itself. SQLite transaction is based on threading and sqflite runs on a separate thread so SQL requests are sent from all isolates on this thread for execution. In the past it was possible to have one isolate running a statement while another isolate was running a transaction which was very bad. This should be solved now.
No and throwing an exception from within a transaction is the best way to rollback a transaction.
Correct.
As long as your properly await all you statements (that is what I wanted to check), it should be fine. Indeed don't use So basically all your assumptions are correct and unless there is a bug in sqflite or your code (and I have to admit that I have avoided background isolates in my own applications), what you experienced (version bumped while not having the expected schema) should not happen...sorry for now having a better response... |
Beta Was this translation helpful? Give feedback.
-
Interesting indeed, this is the missing puzzle I was looking for, I will try to play with Isolates and try to reproduce the issue. Thank you very much for the extended help, and sorry to bother you |
Beta Was this translation helpful? Give feedback.
-
That's correct, the 'server' threads know from which isolate the transaction comes from and suspend other requests.
Unfortunately I don't have much documentation but sometimes I use what I write in discussions (such as this one) and issues to write a small document. You are not bothering me (but sometimes I don't have time), you spent a fair amount of time writing/describing your issue and I know this cross isolate issue is something that needs more attention. For example I wonder what would happen if a background isolate is killed in the middle of a transaction...So far I have avoided using sqflite in a background isolate as much as possible and use workarounds to avoid potential issues but of course that depends of your needs... |
Beta Was this translation helpful? Give feedback.
-
Having a once in a few months issue, the DB version is updated to e.g. v5 but the new tables are not created. Since the upgrade happens in a transaction the full transaction should have completed or rolled back, as SQFlite is setting the version at the end of SqfliteDatabaseMixin.doOpen and I am not doing any exception handling in onUpgrade. The app is opening the DB from a background workmanager Isolate and of course from the front end as well when user opens the App, both background job and frontend app are using the same database open function on the same database file and the DB is never explicitly closed, using
singleInstance: true
in all places which are opening the DB.To counter the issue I am planning to NOT run the upgrade process from the background isolate until the DB is upgraded when user opens the App.
These are the planned steps, is it the right way or there is a more safer way:
singleInstance: false
:openReadOnlyDatabase(dbPath, singleInstance: false)
singleInstance: true
onCreate
onUpgrade
Using
SQFlite 2.2.8+4
withFlutter 3.10
Beta Was this translation helpful? Give feedback.
All reactions