Storing Data
DBFlow provide a few mechanisms by which we store data to the database. The difference of options should not provide confusion but rather allow flexibility in what you decide is the best way to store information.
DB classifies two different kind of DB transactions:
Synchronous
Asynchronous
Synchronous Storage
Saving data synchronous on the main thread should be avoided. We can save data synchronously using a synchronous transaction:
Avoid saving large amounts of models outside of a transaction:
Doing operations on the main thread can block it if you read and write to the DB on a different thread while accessing DB on the main. Instead, use Async Transactions.
Async Transactions
Transactions are ACID in SQLite, meaning they either occur completely or not at all. Using transactions significantly speed up the time it takes to store. So recommendation you should use transactions whenever you can.
Async is the preferred method. Transactions, using the DefaultTransactionManager
, occur on one thread per-database (to prevent flooding from other DB in your app) and receive callbacks on the UI. You can override this behavior and roll your own or hook into an existing system, read here.
Also to use the legacy, priority-based system, read here.
A basic transaction:
The Success
callback runs post-transaction on the UI thread. The Error
callback is called on the UI thread if and only if it is specified and an exception occurs, otherwise it is thrown in the Transaction
as a RuntimeException
.
Note: all exceptions are caught when specifying the callback. Ensure you handle all errors, otherwise you might miss some problems.
ProcessModelTransaction
ProcessModelTransaction
allows for more flexibility and for you to easily operate on a set of Model
in a Transaction
easily. It holds a list of Model
by which you provide the modification method in the Builder
. You can listen for when each are processed inside a normal Transaction
.
It is a convenient way to operate on them:
You can listen to when operations complete for each model via the OnModelProcessListener
. These callbacks occur on the UI thread. If you wish to run them on same thread (great for tests), set runProcessListenerOnSameThread()
to true
.
FastStoreModelTransaction
The FastStoreModelTransaction
is the quickest, lightest way to store a List
of Model
into the database through a Transaction
. Under the hood it just calls modelAdapter.saveAll()
or (insertAll, updateAll, deleteAll) It comes with some restrictions when compared to ProcessModelTransaction
:
1. All Model
must be from same Table/Model Class.
2. No progress listening
3. Can only save
, insert
, or update
the whole list entirely.
What it provides:
1. Reuses DatabaseStatement
, and other classes where possible.
2. Opens and closes own DatabaseStatement
per total execution.
3. Significant speed bump over ProcessModelTransaction
at the expense of flexibility.
Custom TransactionManager
If you prefer to roll your own thread-management system or have an existing system you can override the default system included.
To begin you must implement a ITransactionQueue
:
You must provide ways to add()
, cancel(Transaction)
, and startIfNotAlive()
. The other two methods are optional, but recommended.
startIfNotAlive()
in the DefaultTransactionQueue
will start itself (since it's a thread).
Next you can override the BaseTransactionManager
(not required, see later):
To register it with DBFlow, in your FlowConfig
, you must:
Priority Queue
In versions pre-3.0, DBFlow utilized a PriorityBlockingQueue
to manage the asynchronous dispatch of Transaction
. As of 3.0, it has switched to simply a FIFO queue. To keep the legacy way, a PriorityTransactionQueue
was created.
As seen in Custom Transaction Managers, we provide a custom instance of the DefaultTransactionManager
with the PriorityTransactionQueue
specified:
What this does is for the specified database (in this case AppDatabase
), now require each ITransaction
specified for the database should wrap itself around the PriorityTransactionWrapper
. Otherwise an the PriorityTransactionQueue
wraps the existing Transaction
in a PriorityTransactionWrapper
with normal priority.
To specify a priority, wrap your original ITransaction
with a PriorityTransactionWrapper
:
Last updated