安全地取消后台线程中的ORMLite写入

时间:2012-05-07 23:24:01

标签: android multithreading sqlite ormlite

我正在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以处理以这种方式取消任务的情况时,我是否必须执行任何特殊操作,或者我可以直接退出?

2 个答案:

答案 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"));

有关线程中断时会发生什么的更多信息,请参见此处:

  

What does java.lang.Thread.interrupt() do?


当您将多个对象更新为单个单元或写入多个表时,事务处理。请参阅documentation about transactions,其中包含更新交易内AccountOrder的示例。

此外,如果要更新同一行中的多个字段,则无需使用事务。 update语句被认为是一个单元,数据库应确保该行以原子方式更新。只有在同一个表或单独的表中更新多个不同的行时,才需要进行事务处理。

答案 1 :(得分:0)

ORMLite将利用封面下的sqlite交易。这很可能是一个双阶段提交,它只允许您将事务提交为整个单元。

简而言之,您可以放心,col1和col2只会被修改为单个原子单位。此外,如果中断,则提交将失败,并且将回滚对col1和col2的更改。