2

私はAndroidでsqliteトランザクションを使用しています:

SQLiteDatabase database = sqlite_helper.getWritableDatabase();

database.beginTransaction();
...
database.setTransactionSuccessful();
database.endTransaction();

私の質問は次のとおりです:
1。endTransaction()最後に次のようなコードブロックに配置する必要があります:</ p>

try {
    database.beginTransaction();
    ...
    database.setTransactionSuccessful();
}
finally {
    database.endTransaction();
}

データベース操作中に実行が発生した場合、データベースは「finally」を使用せずに自動的にロールバックされますか?

  1. トランザクションが終了していない場合、他のスレッドが同じデータベースを読み書きできますか?Androidのsqliteはスレッドセーフだと聞きましたが、よくわかりません。取引中に問題が発生するのではないかと思います。別のスレッドが同じ接続で同じデータベースに書き込む場合、エラーが発生しますか?
    私は自分のアプリでこのエラーを見つけたことがありますが、それがスレッドセーフの問題に関連しているかどうかはわかりません:

android.database.sqlite.SQLiteMisuseException: library routine called out of sequence:

、コンパイル中

誰かが私がこれらの質問に答えるのを手伝ってくれますか?どうもありがとう!

4

3 に答える 3

5

1.常にendTransactionをfinallyブロックに配置する必要があります

2.SQLiteのトランザクションはスレッドセーフです。ドキュメントhttp://www.sqlite.org/atomiccommit.htmlを参照してください。

于 2012-10-25T07:05:17.620 に答える
1

常にブロックに入れる必要がendTransaction()あります(ドキュメントfinallyも参照してください)。そうしないと、データベースは例外が発生したことを認識できません。

トランザクションを終了する他の唯一の方法は、接続を閉じることです。この場合、SQLiteはアクティブなトランザクションを自動的にロールバックします。

1つの接続がデータベースに書き込む限り(つまり、トランザクションがアクティブである限り)、他の接続は読み取りまたは書き込みを行うことができません。したがって、トランザクションを終了することを忘れないように注意する必要があります。

複数のスレッドから書き込むことは絶対にしないでください。一方のスレッドがもう一方のスレッドがまだ書き込みをしている間にトランザクションを終了するとどうなりますか?

あなたSQLiteMisuseExceptionは関係があるかもしれませんし、そうでないかもしれません。それはコードを見ずに言うことは不可能です。

于 2012-10-25T07:05:50.943 に答える
0

はい、finallyブロックを使用する必要があります。これが私が使用する単純なスレッドセーフメソッドです。

/**
 * Call for multiple DB insertion transactions.  It is thread safe and fast!
 */
private synchronized void writeTransaction(Runnable task) {
    try {
        db.beginTransaction();
        task.run();
        db.setTransactionSuccessful();
    } finally {
        db.endTransaction();
    }
}

同期されたキーワードは、メソッドをそのオブジェクトを含むものでロックし、スレッドセーフにします。

于 2019-02-27T03:42:52.120 に答える