Reputation: 297
I'm designing out a module in Android that does some processing and then writes to the database using ORMLite transactions. In particular, my background code will be something like:
public class BackgroundOperation implements Runnable {
@Override
public void run() {
//Do some stuff
//Write to the database in a transaction
try {
ORMHelper h = ORMHelper.getDefaultOrmHelper();
final MyModel modelObj = h.myModelDao.queryForId(someId);
TransactionManager.callInTransaction(
h.getConnectionSource(),
new Callable<Void>() {
public Void call() throws Exception {
modelObj.col1 = 10;
modelObj.col2 = "hello";
h.myModel2Dao.update(modelObj);
h.myModel2Dao.create(new MyModel2("a", "b"));
return null;
}
}
);
}
catch (Exception e) {
return null;
}
}
}
This runnable will then be executed by being submitted to a ThreadPoolExecutor. I want to be able to cancel the background thread if needed and am trying to make sure that if the operation is cancelled, then the transaction will simply fail and do nothing. For example, if I do this:
Future f = myThreadPoolExecutor.submit(new BackgroundOperation());
//Some time later
f.cancel(true);
Can I be sure that it will be an all or nothing deal with the transaction in ORMLite. That is, there is no cleanup needed and my modelObj will have either both col1 and col2 set or neither set? Do I have to do anything special when catching the InterruptedException in the Runnable to handle the case when a task is cancelled in this way, or can I simply exit?
Upvotes: 2
Views: 1869
Reputation: 116908
If you call f.cancel(true)
, all that does is interrupt the Thread
which causes wait()
, sleep()
, and some other methods to throw InterruptedException
. It will not cancel the database transaction underway.
If you want, you can check for the interrupted bit in the middle of your IO operations:
h.myModel2Dao.update(modelObj);
if (Thread.currentThread().isInterrupted()) {
throw new RuntimeException("Thread was interrupted");
}
h.myModel2Dao.create(new MyModel2("a", "b"));
For more information about what happens when a thread is interrupted see here:
Transactions are for when you are updating multiple objects as a single unit or writing to multiple tables. See the documentation about transactions which has an example of updating an Account
and an Order
inside of a transaction.
Also, you do not need to use a transaction if you are updating multiple fields in the same row. The update statement is considered to be a single unit and the database should ensure that the row gets updated atomically. Only if you are updating multiple different rows either in the same table or in separate tables do you need a transaction.
Upvotes: 2
Reputation: 11113
ORMLite will utilize the sqlite transactions under the covers. This is most likely a double phase commit which only allows you to commit a transaction as an entire unit.
In short, you can be assured that col1 and col2 will only be modified as a single atomic unit. Also, it if is interrupted the commit will fail and the changes to col1 and col2 will be rolled back.
Upvotes: 0