2

いくつかの処理を実行し、ORMLiteトランザクションを使用してデータベースに書き込むモジュールをAndroidで設計しています。特に、私のバックグラウンドコードは次のようになります。

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をキャッチするときに特別なことをする必要がありますか、それとも単に終了できますか?

4

2 に答える 2

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

スレッドが中断されたときに何が起こるかについての詳細は、ここを参照してください。

java.lang.Thread.interrupt()は何をしますか?


トランザクションは、複数のオブジェクトを1つのユニットとして更新する場合、または複数のテーブルに書き込む場合に使用します。トランザクションの内部と内部を更新する例があるトランザクションに関するドキュメントを参照してください。AccountOrder

また、同じ行の複数のフィールドを更新する場合は、トランザクションを使用する必要はありません。updateステートメントは単一のユニットと見なされ、データベースは行がアトミックに更新されることを確認する必要があります。同じテーブルまたは別々のテーブルのいずれかで複数の異なる行を更新する場合にのみ、トランザクションが必要です。

于 2012-05-08T01:17:39.813 に答える
0

ORMLiteは、内部でsqliteトランザクションを利用します。これは、トランザクションをユニット全体としてのみコミットできる2フェーズコミットである可能性があります。

つまり、col1とcol2は単一の原子単位としてのみ変更されることを保証できます。また、中断された場合、コミットは失敗し、col1とcol2への変更がロールバックされます。

于 2012-05-07T23:39:02.193 に答える