我正在Android中设计一个模块进行一些处理,然后使用ORMLite事务写入数据库。特别是,我的背景代码将类似于:
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;
}
}
}
然后通过提交给ThreadPoolExecutor来执行此runnable。我希望能够在需要时取消后台线程并尝试确保如果操作被取消,那么事务将简单地失败并且什么都不做。例如,如果我这样做:
Future f = myThreadPoolExecutor.submit(new BackgroundOperation());
//Some time later
f.cancel(true);
我可以确定在ORMLite中对事务的全部或全部处理。也就是说,不需要清理,我的modelObj既可以设置col1也可以设置col2,或者都不设置?在Runnable中捕获InterruptedException以处理以这种方式取消任务的情况时,我是否必须执行任何特殊操作,或者我可以直接退出?
答案 0 :(得分:2)
如果您致电f.cancel(true)
,那么所有这一切都会中断Thread
导致wait()
,sleep()
以及其他一些投掷InterruptedException
的方法。它将不取消正在进行的数据库事务。
如果需要,可以在IO操作过程中检查中断位:
h.myModel2Dao.update(modelObj);
if (Thread.currentThread().isInterrupted()) {
throw new RuntimeException("Thread was interrupted");
}
h.myModel2Dao.create(new MyModel2("a", "b"));
有关线程中断时会发生什么的更多信息,请参见此处:
当您将多个对象更新为单个单元或写入多个表时,事务处理。请参阅documentation about transactions,其中包含更新交易内Account
和Order
的示例。
此外,如果要更新同一行中的多个字段,则无需使用事务。 update语句被认为是一个单元,数据库应确保该行以原子方式更新。只有在同一个表或单独的表中更新多个不同的行时,才需要进行事务处理。
答案 1 :(得分:0)
ORMLite将利用封面下的sqlite交易。这很可能是一个双阶段提交,它只允许您将事务提交为整个单元。
简而言之,您可以放心,col1和col2只会被修改为单个原子单位。此外,如果中断,则提交将失败,并且将回滚对col1和col2的更改。