2011-11-16 10 views
71

Ho creato un database. Voglio fare la transazione. SaveCustomer() contiene più di un'istruzione per inserire i record nella tabella Customer, CustomerControl, Profile, Payment in quel momento.Transazione database Android

Quando un utente chiama il metodo SaveCustomer(), tali dati andranno a queste quattro tabelle. Come posso eseguire la transazione? Se una tabella di inserimenti fallisce, è necessario eseguire il rollback di tutto. Ad esempio, quando la terza tabella inserisce il record, ho ricevuto un errore, quindi è necessario eseguire il rollback anche dei record di inserimento della tabella precedente.

Vedi il mio codice:

public void saveCustomer(){ 
    DBAdapter dbAdapter = DBAdapter.getDBAdapterInstance(RetailerOrderKeyActivity.this); 
    dbAdapter.openDataBase(); 
    ContentValues initialValues = new ContentValues(); 
    initialValues.put("CustomerName",customer.getName()); 
    initialValues.put("Address",customer.getAddress()); 
    initialValues.put("CustomerPID",strPID); 
    initialValues.put("Date",strDateOnly); 
    long n = dbAdapter.insertRecordsInDB("Customer", null, initialValues); 

} 

Analogamente altra dichiarazione anche lì.

codice DBAdpter è:

public long insertRecordsInDB(String tableName, String nullColumnHack,ContentValues initialValues) { 
    long n =-1; 
    try { 
     myDataBase.beginTransaction(); 
     n = myDataBase.insert(tableName, nullColumnHack, initialValues); 

     myDataBase.endTransaction(); 
     myDataBase.setTransactionSuccessful(); 
    } catch (Exception e) { 
     // how to do the rollback 
     e.printStackTrace(); 
    } 

    return n; 
} 

Questo è il codice completo:

public class DBAdapter extends SQLiteOpenHelper { 

    private static String DB_PATH = "/data/data/com.my.controller/databases/"; 
    private static final String DB_NAME = "customer"; 
    private SQLiteDatabase myDataBase; 
    private final Context myContext; 
    private static DBAdapter mDBConnection; 


    private DBAdapter(Context context) { 
     super(context, DB_NAME, null, 1); 
     this.myContext = context; 
     DB_PATH = "/data/data/" 
       + context.getApplicationContext().getPackageName() 
       + "/databases/"; 
     // The Android's default system path of your application database is 
     // "/data/data/mypackagename/databases/" 
    } 


    public static synchronized DBAdapter getDBAdapterInstance(Context context) { 
     if (mDBConnection == null) { 
      mDBConnection = new DBAdapter(context); 
     } 
     return mDBConnection; 
    } 


    public void createDataBase() throws IOException { 
     boolean dbExist = checkDataBase(); 
     if (dbExist) { 
      // do nothing - database already exist 
     } else { 
      // By calling following method 
      // 1) an empty database will be created into the default system path of your application 
      // 2) than we overwrite that database with our database. 
      this.getReadableDatabase(); 
      try { 
       copyDataBase(); 
      } catch (IOException e) { 
       throw new Error("Error copying database"); 
      } 
     } 
    } 


    private boolean checkDataBase() { 
     SQLiteDatabase checkDB = null; 

     try { 
      String myPath = DB_PATH + DB_NAME; 
      checkDB = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READONLY); 

     } catch (SQLiteException e) { 
      // database does't exist yet. 
     } 
     if (checkDB != null) { 
      checkDB.close(); 
     } 
     return checkDB != null ? true : false; 
    } 


    private void copyDataBase() throws IOException { 
     InputStream myInput = myContext.getAssets().open(DB_NAME); 
     String outFileName = DB_PATH + DB_NAME; 
     OutputStream myOutput = new FileOutputStream(outFileName); 
    byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myInput.read(buffer)) > 0) { 
      myOutput.write(buffer, 0, length); 
     } 
      // Close the streams 
     myOutput.flush(); 
     myOutput.close(); 
     myInput.close(); 
    } 

    /** 
    * Open the database 
    * @throws SQLException 
    */ 
    public void openDataBase() throws SQLException { 
     String myPath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);  
    } 


    @Override 
    public synchronized void close() { 
     if (myDataBase != null) 
      myDataBase.close(); 
     super.close(); 
    } 

    /** 
    * Call on creating data base for example for creating tables at run time 
    */ 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
    } 


    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     db.execSQL("ALTER TABLE WMPalmUploadControl ADD Testing int"); 

    } 

    public void upgradeDb(){ 
     onUpgrade(myDataBase, 1, 2); 
    } 

    public Cursor selectRecordsFromDB(String tableName, String[] tableColumns, 
      String whereClase, String whereArgs[], String groupBy, 
      String having, String orderBy) { 
     return myDataBase.query(tableName, tableColumns, whereClase, whereArgs, 
       groupBy, having, orderBy); 
    } 


    public ArrayList<ArrayList<String>> selectRecordsFromDBList(String tableName, String[] tableColumns, 
      String whereClase, String whereArgs[], String groupBy, 
      String having, String orderBy) {   

     ArrayList<ArrayList<String>> retList = new ArrayList<ArrayList<String>>(); 
      ArrayList<String> list = new ArrayList<String>(); 
      Cursor cursor = myDataBase.query(tableName, tableColumns, whereClase, whereArgs, 
        groupBy, having, orderBy);   
      if (cursor.moveToFirst()) { 
      do { 
       list = new ArrayList<String>(); 
       for(int i=0; i<cursor.getColumnCount(); i++){     
        list.add(cursor.getString(i)); 
       } 
       retList.add(list); 
      } while (cursor.moveToNext()); 
      } 
      if (cursor != null && !cursor.isClosed()) { 
      cursor.close(); 
      } 
      return retList; 

    } 


    public long insertRecordsInDB(String tableName, String nullColumnHack,ContentValues initialValues) { 
     long n =-1; 
     try { 
      myDataBase.beginTransaction(); 
      n = myDataBase.insert(tableName, nullColumnHack, initialValues); 

      myDataBase.endTransaction(); 
      myDataBase.setTransactionSuccessful(); 
     } catch (Exception e) { 
      // how to do the rollback 
      e.printStackTrace(); 
     } 

     return n; 
    } 


    public boolean updateRecordInDB(String tableName, 
      ContentValues initialValues, String whereClause, String whereArgs[]) { 
     return myDataBase.update(tableName, initialValues, whereClause, 
       whereArgs) > 0;    
    } 

    public int updateRecordsInDB(String tableName, 
      ContentValues initialValues, String whereClause, String whereArgs[]) { 
     return myDataBase.update(tableName, initialValues, whereClause, whereArgs);  
    } 


    public int deleteRecordInDB(String tableName, String whereClause, 
      String[] whereArgs) { 
     return myDataBase.delete(tableName, whereClause, whereArgs); 
    } 


    public Cursor selectRecordsFromDB(String query, String[] selectionArgs) { 
     return myDataBase.rawQuery(query, selectionArgs);  
    } 


    public ArrayList<ArrayList<String>> selectRecordsFromDBList(String query, String[] selectionArgs) {  
      ArrayList<ArrayList<String>> retList = new ArrayList<ArrayList<String>>(); 
      ArrayList<String> list = new ArrayList<String>(); 
      Cursor cursor = myDataBase.rawQuery(query, selectionArgs);    
      if (cursor.moveToFirst()) { 
      do { 
       list = new ArrayList<String>(); 
       for(int i=0; i<cursor.getColumnCount(); i++){     
        list.add(cursor.getString(i)); 
       } 
       retList.add(list); 
      } while (cursor.moveToNext()); 
      } 
      if (cursor != null && !cursor.isClosed()) { 
      cursor.close(); 
      } 
      return retList; 
     } 

} 

database lock issue in HTC Desire.

Desidero eseguire il rollback se si sono verificati problemi durante l'inserimento dei dati della tabella.

Please help me

Grazie.

ho guardato questa stessa domanda correlata:

risposta

24

si dovrebbe aggiungere endTransaction nel vostro finally, non nel vostro blocco try

finally { 
    myDataBase.endTransaction(); 
    } 

Le modifiche verranno rollback eventuale transazione è conclusa senza essere contrassegnato come pulito (chiamando setTransactionSuccessful). Altrimenti saranno commessi.

+1

Grazie per l'informazione. Nel mio 'SaveCustomer() 'chiamerò' long n = dbAdapter.insertRecordsInDB (" Cliente ", null, initialValues);" in 4 volte con record diversi. Farà il rollback di tutto, se ci sono degli errori anche nel tavolo centrale. Ho 4 tavoli. Aggiungerei record in 4 tavoli con record diversi. – Kartheepan

258

In realtà si sta sbagliando. È necessario impostare la transazione iniziale se si dispone di più record da inserire nel database o se è necessario eseguire il rollback dei dati da un'altra tabella se si verifica un problema nell'inserimento di dati in una delle tabelle del database.

Per esempio

avere due tabelle

  1. Un
  2. B

Ora si desidera inserire i dati in queste due tabelle, ma si dovrà far ritirare transazione se si otterrà qualsiasi errore al momento dell'inserimento dei dati nelle tabelle.

Ora avete inserire correttamente i dati in tabella A e ora si sta cercando di inserire i dati nella tabella B.Now se si ottiene errore al momento di inserire dati nella tabella B, allora è necessario eliminare i dati rilevanti da tavolo A significa che devi effettuare il rollback della transazione.

Come si può utilizzare la transazione database in Android

  1. Se si desidera avviare la transazione v'è un metodo beginTransaction()
  2. Se si vuole il commit della transazione v'è un metodo setTransactionSuccessful(), che impegnerà i valori nella banca dati
  3. Se la transazione è stata avviata, è necessario chiudere la transazione, quindi esiste un metodo endTransaction() che terminerà la transazione del database

Ora ci sono due punti principali

  1. Se si desidera impostare operazione di successo è necessario scrivere setTransactionSuccessful() e poi endTransaction() dopo beginTransaction()
  2. Se si desidera eseguire il rollback la transazione allora avete bisogno di endTransaction() senza commettendo la transazione tramite setTransactionSuccessful().

È possibile ottenere informazioni dettagliate sulla transazione database SQLite da here

Nel tuo caso

È possibile chiamare la funzione saveCustomer() nel try e catch blocchi

db.beginTransaction(); 
try { 
    saveCustomer(); 
    db.setTransactionSuccessful(); 
} catch { 
    //Error in between database transaction 
} finally { 
    db.endTransaction(); 
} 
+3

Grazie per questa informazione. È più utile per me !!!. Grazie ancora – Piraba

+11

Dovresti aggiungere 'endTransaction' alla fine, non nel tuo blocco try. – VansFannel

+6

@VansFannel hai ragione è finalmente il posto migliore per chiudere la transazione del database. grazie per renderlo migliore – Dharmendra

11

Inserire Registra utilizzando la transazione, questo è molto veloce

String sql = "INSERT INTO table (col1, col2) VALUES (?, ?)"; 
db.beginTransaction(); 

SQLiteStatement stmt = db.compileStatement(sql); 
for (int i = 0; i < values.size(); i++) { 
    stmt.bindString(1, values.get(i).col1); 
    stmt.bindString(2, values.get(i).col2); 
    stmt.execute(); 
    stmt.clearBindings(); 
} 

db.setTransactionSuccessful(); 
db.endTransaction(); 
Problemi correlati