2009-01-06 5 views
12

J'utilise SQLite3 pour le développement de l'iPhone et j'essaie d'intégrer quelques instructions d'insertion dans une transaction. Actuellement, j'ai le code ci-dessous qui fonctionne correctement mais après avoir lu une autre question sur SO, je me suis rendu compte qu'il serait préférable de les avoir en une seule transaction plutôt qu'une seule. Je n'ai pas trouvé l'appel de l'API C pour commencer et valider une transaction. Une partie du code est en Objective-C mais je ne pense pas que cela soit vraiment pertinent.Transactions API SQLite 3 C

- (void)saveAnimals { 
    //Insert all the animals into the zoo database 
    int i; 

    const char *sql = "insert into Animal(Zoo_ID, Animal_Num, Animal_Text) Values(?, ?, ?)"; 
    for (i = 0; i < ([[self animalArray] count] - 1); i++) { 

     if(addStmt == nil) { 
      if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK) 
       NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database)); 
     } 
     int animalNum = [[[self animalArray] objectAtIndex:i] animal_Number]; 
     NSString *animalText = [[NSString alloc] initWithString:[[[self animalArray] objectAtIndex:i] animal_Text]]; 
     sqlite3_bind_int(addStmt, 1, zoo_ID); 
     sqlite3_bind_int(addStmt, 2, animalNum);  
     sqlite3_bind_text(addStmt, 3, [animalText UTF8String], -1, SQLITE_TRANSIENT); 
     [animalText release]; 
     if(SQLITE_DONE != sqlite3_step(addStmt)) { 
      NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 
     } 

     //Reset the add statement. 
     sqlite3_reset(addStmt);  
    } 
} 

Ce que je pense que les besoins à faire serait de prendre la commande sqlite3_prepare_v2 hors de la boucle, commencer la transaction, passer par la boucle, valider la transaction. Cependant, je ne suis pas sûr de savoir quels sont les appels pour "démarrer la transaction" et "engager la transaction". Et est-ce que je continuerais à utiliser sqlite3_step? Merci de votre aide.

Répondre

32

Démarrer une transaction avec: sqlite3_exec(db, "BEGIN", 0, 0, 0);

Engagez une transaction avec: sqlite3_exec(db, "COMMIT", 0, 0, 0);

+6

On pourrait penser qu'il y aurait une API plus propre pour cela ... Pourquoi ne pas comprennent juste un sqlite3_exec_trans_begin (db) appel ... – klynch

+0

fait 'sqlite3_exec (db," ​​BEGIN ", 0, 0, 0);' échoue jamais si le fichier de base de données est accédé simultanément? –

+2

@afriza, BEGIN est une opération différée. Différé signifie qu'aucun verrou n'est acquis sur la base de données tant que la base de données n'a pas été accédée pour la première fois. Ainsi, avec une transaction différée, l'instruction BEGIN elle-même ne fait rien au système de fichiers. Les verrous ne sont pas acquis avant la première opération de lecture ou d'écriture. Voir http://www.sqlite.org/lang_transaction.html pour d'autres variations sur BEGIN qui tentent d'obtenir des verrous. –