Transazione database Android


84

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

Quando un utente chiama il SaveCustomer()metodo, i dati andranno a queste 4 tabelle. Quindi come posso eseguire la transazione? Se l'inserimento di una tabella non è riuscito, è necessario ripristinare tutto. Ad esempio, quando la terza tabella inserisce il record, ho ricevuto un errore, quindi è necessario ripristinare anche i record di inserimento delle due tabelle precedenti.

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

}

Allo stesso modo altra dichiarazione anche lì.

Il 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;
       }

}

problema di blocco del database in HTC Desire .

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

mi aiuti per favore

Grazie.

Ho guardato questa stessa domanda correlata:

Risposte:


279

In realtà stai sbagliando. È necessario impostare la transazione iniziale se si hanno 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 dei dati in una delle tabelle del database.

Per esempio

Hai due tavoli

  1. UN
  2. B

Ora vuoi inserire i dati in queste due tabelle ma dovrai eseguire il rollback della transazione se riceverai un errore al momento dell'inserimento dei dati nelle tabelle.

Ora hai inserito correttamente i dati nella tabella A e ora stai provando a inserire i dati nella tabella B.Ora se ricevi un errore al momento dell'inserimento dei dati nella tabella B, devi eliminare i dati rilevanti dalla tabella A, significa che tu eseguire il rollback della transazione.

Come puoi utilizzare la transazione del database in Android

  1. Se vuoi avviare la transazione c'è un metodo beginTransaction()
  2. Se si desidera eseguire il commit della transazione, esiste un metodo setTransactionSuccessful()che eseguirà il commit dei valori nel database
  3. Se hai avviato la transazione, devi chiudere la transazione, quindi esiste un metodo endTransaction()che terminerà la transazione del database

Ora ci sono due punti principali

  1. Se vuoi impostare la transazione con successo devi scrivere setTransactionSuccessful()e poi endTransaction()dopobeginTransaction()
  2. Se desideri eseguire il rollback della transazione, devi farlo endTransaction()senza eseguire il commit della transazione da parte di setTransactionSuccessful().

È possibile ottenere informazioni dettagliate sulla transazione del database SQLite da qui

Nel tuo caso

Puoi chiamare la tua saveCustomer()funzione in try and catch blocks

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

11
Dovresti aggiungere il endTransactiontuo finalmente, non il tuo blocco try.
VansFannel

6
@VansFannel hai ragione finalmente è il posto migliore per chiudere la transazione del database. grazie per averlo migliorato.
Dharmendra

25

dovresti aggiungere endTransactionnel tuo finally, non nel tuo blocco try

 finally {
     myDataBase.endTransaction();
   }

Le modifiche verranno annullate se una transazione viene terminata senza essere contrassegnata come pulita (chiamando setTransactionSuccessful). Altrimenti verranno impegnati.


1
Grazie per l'informazione. Nel mio 'SaveCustomer () `chiamerò' long n = dbAdapter.insertRecordsInDB (" Customer ", null, initialValues); ' in 4 tempi con record diversi. Ripristinerà tutto, se si verificano errori anche nella tabella centrale. Ho 4 tabelle. È necessario aggiungere record in 4 tabelle con record diversi.?
Kartheepan

17

Inserisci record 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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.