I have a certain update method in my Android App, which generates quite an amount of data - up to hundreds of database entries. I also have a background service, aside from the UI thread. Both threads have to execute the update method, sometimes even at the same time - basically, this is about generating and caching data to display. Both the UI and background service need this data.
Currently, I have wrapped the method's execution in an ORMLite transaction, which maps to an ordinary SQLite transaction. However, I am afraid that this will bite me in the butt one day, when some race condition screws up the data cache.
The question: Do SQLite transactions protect me from concurrent execution, or should I rather implement some kind of worker thread which is spawned when the generator-method shall start, or blocking if the generator-method is already running?
UPDATE:
I have decided to not rely on SQLite logic for the protection of my high-level Java method. The solution was for me as follows:
- Wrap the generating part of the method with
synchronized
- Introduce a variable which tracks the last time of executing the method (set at the end of the method, so it is the marker of execution END)
- First thing in the
synchronized
section, check if the last execution is in a specific threshold (e.g. <= 100ms in the past)- If yes, skip generation
- If no, perform generation
In this way, duplicate generation should not take place, since when the method is accessed from two threads at the same time, the first will generate, but the second will not. The most important part for me here is that it is still blocking, since both threads rely on the generation having taken place after they have called the method.