web-dev-qa-db-ja.com

beginTransaction()、endTransaction()、およびsetTransactionSuccessful()。彼らは正確に何をしますか?

データベースからアイテムを挿入、クエリ、更新、および削除するときに同期を提供する必要があります。私が理解している限り、beginTransaction()beginTransactionNonExclusive()は私が必要とするメソッドです。

さらに SQLiteドキュメントEXCLUSIVEIMMEDIATE、およびDEFERREDについて非常によく説明しています。

トランザクションは、遅延、即時、または排他的です。据え置きとは、データベースが最初にアクセスされるまで、データベースでロックが取得されないことを意味します。

トランザクションが即時の場合、データベースが使用されるのを待たずに、BEGINコマンドが実行されるとすぐに、すべてのデータベースでRESERVEDロックが取得されます。 BEGIN IMMEDIATEの後、他のデータベース接続はデータベースに書き込むことも、BEGIN IMMEDIATEまたはBEGIN EXCLUSIVEを実行することもできません。ただし、他のプロセスは引き続きデータベースから読み取ることができます。

排他トランザクションにより、すべてのデータベースでEXCLUSIVEロックが取得されます。 BEGIN EXCLUSIVEの後、read_uncommitted接続以外の他のデータベース接続はデータベースを読み取ることができなくなり、トランザクションが完了するまで、例外なく他の接続はデータベースに書き込むことができなくなります。

一部のスレッドがデータベースを操作している間、不要な挿入やクエリからの保護を提供するようです。しかし、同期が保証されているかどうかはわかりません。

insertContentProviderメソッドがあります。

_@Override
public Uri insert(Uri baseUri, ContentValues values) {
    try {
        mDatabase = mHelper.getWritableDatabase();
        mDatabase.beginTransaction(); // EXCLUSIVE
        switch (sUriMatcher.match(baseUri)) {
        case UriCodes.COUNTRIES:
        case UriCodes.CONTINENTS:
        case UriCodes.ORGS:
            String table = baseUri.getLastPathSegment();
            long rowId = mDatabase.insert(table, null, values);
            Uri uri = Uri.withAppendedPath(baseUri, Long.toString(rowId));
            mDatabase.setTransactionSuccessful();
            return uri;

        default:
            mDatabase.endTransaction();
            throw new IllegalArgumentException(UNSUPPORTED_URI + SPACE + baseUri);
        }
    } finally {
        mDatabase.endTransaction();
    }
}
_

以前は、beginTransaction()endTransaction()、およびsetTransactionSuccessful()がなければ問題はありませんでした。本当に追加する必要がありますか?

15
Maksim Dmitriev

Androidはもちろんオフです。信頼性の高いデータ操作を行う場合は、以下のサポートされている方法を使用することが重要です。

BeginTransaction();
SetTransactionSuccessful();
EndTransaction(); 

詳細については、これを参照してください… In Androidデータベースを操作するときにトランザクションを使用することが非常に重要です。

12
Shujaat Abdi

はい、それはアプリをスムーズにします.SQLiteは1つのカーソルを1つのトランザクションと見なすため、大量のデータを挿入する前にbegin transaction()を使用し、次にsetTransactionSuccessful()を使用してから、最後にendTransaction()を使用すると、SQLiteはこれを考慮します数百のトランザクションではなく、1つのトランザクションとしてイベントを挿入します。

1
juechen wang