Операционная система Android
Я создал базу данных. Я хочу сделать Сделку. SaveCustomer()
содержит более одного оператора для вставки записей в таблицу Customer, CustomerControl, Profile, Payment
в то время.
Когда пользователь вызывает SaveCustomer()
тогда эти данные перейдут в эти 4 таблицы. Как я могу выполнить транзакцию? Если одна таблица встает с ошибкой, тогда необходимо отбросить все. Например, когда 3-я таблица вставляет запись, я получил ошибку, тогда вам нужно также отменить предыдущие записи вставки двух таблиц.
Смотрите мой код:
- Соответствующий шаблон является строгим, но для элемента 'tx: annotation-driven'
- Django: как я могу защитить от одновременной модификации записей в базе данных
- Дублирование fragmentов на транзакции fragmentов
- Откат вложенной / дочерней транзакции
- Что произойдет, если вы не совершаете транзакцию с базой данных (скажем, SQL Server)?
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); }
Аналогично другое заявление также есть.
Код 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; }
Это полный код:
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> selectRecordsFromDBList(String tableName, String[] tableColumns, String whereClase, String whereArgs[], String groupBy, String having, String orderBy) { ArrayList<ArrayList> retList = new ArrayList<ArrayList>(); ArrayList list = new ArrayList(); Cursor cursor = myDataBase.query(tableName, tableColumns, whereClase, whereArgs, groupBy, having, orderBy); if (cursor.moveToFirst()) { do { list = new ArrayList(); for(int i=0; i 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> selectRecordsFromDBList(String query, String[] selectionArgs) { ArrayList<ArrayList> retList = new ArrayList<ArrayList>(); ArrayList list = new ArrayList(); Cursor cursor = myDataBase.rawQuery(query, selectionArgs); if (cursor.moveToFirst()) { do { list = new ArrayList(); 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; } }
проблема с блокировкой базы данных в HTC Desire .
Я хочу вернуться, если возникли какие-либо проблемы при вставке данных таблицы.
пожалуйста, помогите мне
Благодарю.
Я посмотрел на этот же вопрос:
- Использование транзакций или SaveChanges (false) и AcceptAllChanges ()?
- Oracle: как узнать, ожидает ли транзакция?
- javax.transaction.Transactional vs org.springframework.transaction.annotation.Transactional
- Фиксация «Тайм-аут блокировки ожидания превышен; попробуйте перезапустить транзакцию «за« застрявшую »таблицу Mysql?
- Структура Entity Framework и уровень изоляции транзакций
- EJB-транзакции в локальных методах-вызовах
- Как сделать большие неблокирующие обновления в PostgreSQL?
- Каков «лучший» способ делать распределенные транзакции в нескольких базах данных с использованием Spring и Hibernate
На самом деле вы поступаете неправильно. Вы должны установить начальную транзакцию, если у вас есть несколько записей для вставки в базу данных или если вам приходится откатывать данные из другой таблицы, если есть проблема с вставкой данных в одну из таблиц базы данных.
Например
У вас есть две таблицы
- В
Теперь вы хотите вставить данные в эти две таблицы, но вам придется откат транзакции, если вы получите какую-либо ошибку во время ввода данных в таблицы.
Теперь вы успешно вставляете данные в таблицу A, и теперь вы пытаетесь вставить данные в таблицу B. Теперь, если вы получаете ошибку во время вставки данных в таблицу B, вам необходимо удалить соответствующие данные из таблицы A, что означает, что вы должны отменить транзакцию.
Как использовать транзакцию базы данных в Android
- Если вы хотите начать транзакцию, существует метод
beginTransaction()
- Если вы хотите зафиксировать транзакцию, существует метод
setTransactionSuccessful()
который будет фиксировать значения в базе данных - Если вы запустили транзакцию, вам нужно закрыть транзакцию, поэтому существует метод
endTransaction()
который завершит транзакцию с базой данных
Теперь есть два основных момента
- Если вы хотите установить успешную транзакцию, вам нужно написать
setTransactionSuccessful()
а затемendTransaction()
послеbeginTransaction()
- Если вы хотите отменить транзакцию, вам необходимо
endTransaction()
не совершая транзакцию с помощьюsetTransactionSuccessful()
.
Вы можете получить подробную информацию о транзакции базы данных SQLite отсюда
В твоем случае
Вы можете вызвать saveCustomer()
в try и catch saveCustomer()
db.beginTransaction(); try { saveCustomer(); db.setTransactionSuccessful(); } catch { //Error in between database transaction } finally { db.endTransaction(); }
вы должны добавить endTransaction
в свою очередь, а не в блок try
finally { myDataBase.endTransaction(); }
Изменения будут отменены, если какая-либо транзакция будет завершена без маркировки как чистой (путем вызова setTransactionSuccessful). В противном случае они будут совершены.
Вставить запись с помощью транзакции, это очень быстро
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();