2009-01-06 16 views
12

Ich verwende SQLite3 für die iPhone-Entwicklung und ich versuche, einige Insert-Anweisungen in eine Transaktion zu wickeln. Derzeit habe ich den untenstehenden Code, der richtig funktioniert, aber nachdem ich eine andere Frage zu SO gelesen habe, wurde mir klar, dass es besser wäre, diese in einer Transaktion als in einer zu haben. Ich konnte den Aufruf der C-API nicht finden, um eine Transaktion zu beginnen und zu committen. Ein Teil des Codes ist in Objective-C, aber ich glaube nicht, dass das für die Frage relevant ist.SQLite 3 C API-Transaktionen

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

Was denke ich getan werden muss, würde aus der die sqlite3_prepare_v2 Befehl für eine Schleife nehmen, starten Sie die Transaktion, gehen Sie durch die for-Schleife, um die Transaktion zu begehen. Allerdings bin ich mir nicht sicher, was die Aufrufe "Starten der Transaktion" und "Commit der Transaktion" sind. Und würde ich immer noch sqlite3_step verwenden? Danke für Ihre Hilfe.

Antwort

32

eine Transaktion mit Start: sqlite3_exec(db, "BEGIN", 0, 0, 0);

eine Transaktion Commit mit: sqlite3_exec(db, "COMMIT", 0, 0, 0);

+6

Sie denken, es wäre ein sauberer API dafür wäre ... Warum sie eine sqlite3_exec_trans_begin (db) Anruf gerade nicht enthalten ... – klynch

+0

schlägt 'sqlite3_exec (db," ​​BEGIN ", 0, 0, 0);' immer fehl, wenn auf die Datenbankdatei gleichzeitig zugegriffen wird? –

+2

@ Afrizia, BEGIN ist eine verzögerte Operation. Zurückgestellt bedeutet, dass in der Datenbank keine Sperren erfasst werden, bis auf die Datenbank zum ersten Mal zugegriffen wird. Bei einer verzögerten Transaktion führt die BEGIN-Anweisung selbst nichts zum Dateisystem. Sperren werden erst beim ersten Lese- oder Schreibvorgang erfasst. Weitere Variationen zu BEGIN, die versuchen, Sperren zu erhalten, finden Sie unter http://www.sqlite.org/lang_transaction.html. –