我正在 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 来执行。我希望能够在需要时取消后台线程,并尝试确保如果取消操作,则事务将失败并且不执行任何操作。例如,如果我这样做:
Future f = myThreadPoolExecutor.submit(new BackgroundOperation());
//Some time later
f.cancel(true);
我可以确定 ORMLite 中的事务处理是全有或全无吗?也就是说,不需要清理,我的 modelObj 将同时设置 col1 和 col2 或两者都不设置?当捕获 Runnable 中的 InterruptedException 来处理以这种方式取消任务的情况时,我是否需要做一些特殊的事情,或者我可以直接退出吗?
最佳答案
如果您调用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
的示例。
此外,如果您要更新同一行中的多个字段,则不需要使用事务。更新语句被视为单个单元,数据库应确保该行以原子方式更新。仅当您要更新同一个表或不同表中的多个不同行时,才需要事务。
关于android - 安全取消后台线程中的 ORMLite 写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10490479/