web-dev-qa-db-fra.com

beginTransaction (), endTransaction () et setTransactionSuccessful (). Que font-ils exactement?

Je dois assurer la synchronisation lors de l'insertion, de l'interrogation, de la mise à jour et de la suppression d'éléments d'une base de données. Autant que je sache, beginTransaction() et beginTransactionNonExclusive() sont les méthodes dont j'ai besoin. 

En outre la documentation SQLite décrit très bien EXCLUSIVE, IMMEDIATE et DEFERRED

Les transactions peuvent être différées, immédiates ou exclusives. Différé signifie qu'aucun verrou n'est acquis sur la base de données jusqu'à ce que la base de données soit d'abord accédé. 

Si la transaction est immédiate, les verrous RESERVED sont acquis le toutes les bases de données dès que la commande BEGIN est exécutée, sans attendre que la base de données soit utilisée. Après un début immédiat, pas d'autre connexion à la base de données pourra écrire dans la base de données ou faire un COMMENCE IMMÉDIATEMENT OU COMMENCE EXCLUSIVE. D'autres processus peuvent continuer jusqu'à lire à partir de la base de données, cependant. 

Une transaction exclusive entraîne l’acquisition de verrous EXCLUSIVE sur tous bases de données. Après BEGIN EXCLUSIVE, aucune autre connexion à la base de données sauf pour read_uncommitted, les connexions pourront lire le fichier base de données et aucune autre connexion sans exception sera en mesure de écrivez la base de données jusqu'à la fin de la transaction.

Il semble fournir une certaine protection contre les insertions et les requêtes non désirées pendant que certains threads travaillent avec la base de données. Mais je ne suis pas sûr que cela garantisse la synchronisation.

Il existe la méthode insert de ma ContentProvider.

@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();
    }
}

Je n’ai jamais eu de problèmes sans beginTransaction(), endTransaction() et setTransactionSuccessful() auparavant. Ai-je vraiment besoin de les ajouter?

15
Maksim Dmitriev

Bien sûr avec Android! Si vous travaillez pour une manipulation de données fiable, il est important d'utiliser les méthodes prises en charge suivantes.

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

Pour en savoir plus, voir… Sous Android, il est extrêmement important d'utiliser des transactions pour travailler avec des bases de données.

12
Shujaat Abdi

Oui, cela rend l'application lisse. Parce que SQLite considère un curseur comme une transaction, si nous utilisons begin transaction () avant d'insérer une grande quantité de données, nous utilisons setTransactionSuccessful () second, puis endTransaction () dans insérer l'événement comme une transaction, au lieu de centaines de transactions.

1
juechen wang