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 :
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.
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.
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.
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.
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
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
beginTransaction()
setTransactionSuccessful()
which will commit the values in the databaseendTransaction()
which will end your database transactionNow there are two main points
setTransactionSuccessful()
and then endTransaction()
after beginTransaction()
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(); }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With