Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Database Transaction

I have created a database. I want to do the Transaction. SaveCustomer() contains more than one statement to insert records into Customer, CustomerControl, Profile, Payment table at that time.

When a user calls SaveCustomer() method then that data will go to these 4 tables.so How can I do the transaction? If one table inserts failed then need to roll back everything. For example, when 3rd table inserts the record I got an error, then need to roll back previous two table's insert records also.

See my code:

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

Likewise other statement also there.

DBAdpter code is :

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

This is the full code:

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.

I want to roll back if there any issues occurred when inserting the table data.

Please help me

Thanks.

I looked this same related question :

like image 789
Kartheepan Avatar asked Nov 16 '11 06:11

Kartheepan


People also ask

What is a transaction in Android?

android.arch.persistence.room.Transaction. Marks a method in a Dao class as a transaction method. When used on a non-abstract method of an abstract Dao class, the derived implementation of the method will execute the super method in a database transaction. All the parameters and return types are preserved.

What is SQLite transaction in Android?

Advertisements. A transaction is a unit of work that is performed against a database. Transactions are units or sequences of work accomplished in a logical order, whether in a manual fashion by a user or automatically by some sort of a database program.

What is database transaction example?

Any logical calculation done in a consistent mode in a database is known as a transaction. One example is a transfer from one bank account to another: the complete transaction requires subtracting the amount to be transferred from one account and adding that same amount to the other.

How do I use SQLite transactions?

SQLite transaction statements First, open a transaction by issuing the BEGIN TRANSACTION command. After executing the statement BEGIN TRANSACTION , the transaction is open until it is explicitly committed or rolled back. Second, issue SQL statements to select or update data in the database.


2 Answers

Actually you are doing wrong. You have to set begin transaction if you have multiple records to insert into database or if you have to rollback data from other table if there is a problem in inserting data in one of the database table.

For example

You have two tables

  1. A
  2. B

Now you want to insert data in these two tables but you will have to rollback transaction if you will get any error at the time of inserting data in the tables.

Now you have successfully insert data in table A and now you are trying to insert data in the table B.Now if you get error at the time of inserting data in the table B then you have to delete relevant data from table A that means you have to rollback the transaction.

How you can use database transaction in Android

  1. If you want to start the transaction there is a method beginTransaction()
  2. If you want to commit the transaction there is a method setTransactionSuccessful() which will commit the values in the database
  3. If you had start the transaction you need to close the transaction so there is a method endTransaction() which will end your database transaction

Now there are two main points

  1. If you want to set transaction successful you need to write setTransactionSuccessful() and then endTransaction() after beginTransaction()
  2. If you want to rollback your transaction then you need to endTransaction() without committing the transaction by setTransactionSuccessful().

You can get detailed information about the SQLite database transaction from here

In your case

You can call your saveCustomer() function in try and catch blocks

db.beginTransaction(); try {     saveCustomer();     db.setTransactionSuccessful(); } catch {     //Error in between database transaction  } finally {     db.endTransaction(); } 
like image 94
Dharmendra Avatar answered Oct 13 '22 04:10

Dharmendra


you should add endTransaction in your finally, not in your try block

 finally {      myDataBase.endTransaction();    } 

The changes will be rolled back if any transaction is ended without being marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.

like image 27
Labeeb Panampullan Avatar answered Oct 13 '22 04:10

Labeeb Panampullan