Android 数据库事务 [英] Android Database Transaction

查看:34
本文介绍了Android 数据库事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个数据库.我想做交易.SaveCustomer() 包含多个语句,用于将记录插入到 Customer、CustomerControl、Profile、Payment 表中.

当用户调用 SaveCustomer() 方法时,该数据将转到这 4 个表中.所以我该如何进行交易?如果一张表插入失败,则需要回滚所有内容.例如,当第三张表插入记录时出现错误,则还需要回滚前两张表的插入记录.

查看我的代码:

public void saveCustomer(){DBAdapter dbAdapter = DBAdapter.getDBAdapterInstance(RetailerOrderKeyActivity.this);dbAdapter.openDataBase();ContentValues initialValues = new ContentValues();initialValues.put("CustomerName",customer.getName());initialValues.put("地址",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) {长 n = -1;尝试 {myDataBase.beginTransaction();n = myDataBase.insert(tableName, nullColumnHack, initialValues);myDataBase.endTransaction();myDataBase.setTransactionSuccessful();} 捕获(异常 e){//如何进行回滚e.printStackTrace();}返回 n;}

这是完整的代码:

public class DBAdapter extends SQLiteOpenHelper {private static String DB_PATH = "/data/data/com.my.controller/databases/";private static final String DB_NAME = "customer";私有 SQLiteDatabase myDataBase;私有最终上下文 myContext;私有静态 DBAdapter mDBConnection;私有 DBAdapter(上下文上下文){超级(上下文,DB_NAME,空,1);this.myContext = 上下文;DB_PATH = "/数据/数据/"+ context.getApplicationContext().getPackageName()+ "/数据库/";//你的应用数据库的Android默认系统路径是//"/data/data/mypackagename/databases/"}公共静态同步 DBAdapter getDBAdapterInstance(上下文上下文){如果(mDBConnection == null){mDBConnection = 新 DBAdapter(上下文);}返回 mDBConnection;}public void createDataBase() 抛出 IOException {布尔 dbExist = checkDataBase();如果(数据库存在){//什么都不做——数据库已经存在} 别的 {//通过调用下面的方法//1) 一个空的数据库将被创建到你的应用程序的默认系统路径中//2) 比我们用我们的数据库覆盖那个数据库.this.getReadableDatabase();尝试 {复制数据库();} catch (IOException e) {throw new Error("复制数据库出错");}}}私有布尔值 checkDataBase() {SQLiteDatabase checkDB = null;尝试 {String myPath = DB_PATH + DB_NAME;checkDB = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READONLY);} catch (SQLiteException e) {//数据库还不存在.}如果(检查数据库!= null){checkDB.close();}返回 checkDB != null ?真假;}private void copyDataBase() 抛出 IOException {InputStream myInput = myContext.getAssets().open(DB_NAME);String outFileName = DB_PATH + DB_NAME;OutputStream myOutput = new FileOutputStream(outFileName);字节[]缓冲区=新字节[1024];整数长度;while ((length = myInput.read(buffer)) > 0) {myOutput.write(buffer, 0, length);}//关闭流myOutput.flush();myOutput.close();myInput.close();}/*** 打开数据库* @throws SQLException*/public void openDataBase() 抛出 SQLException {String myPath = DB_PATH + DB_NAME;myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);}@覆盖公共同步无效关闭(){如果(我的数据库!= null)myDataBase.close();超级关闭();}/*** 调用创建数据库,例如在运行时创建表*/@覆盖公共无效onCreate(SQLiteDatabase db){}@覆盖public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("ALTER TABLE WMPalmUploadControl AD​​D Testing int");}公共无效升级数据库(){onUpgrade(myDataBase, 1, 2);}public Cursor selectRecordsFromDB(String tableName, String[] tableColumns,String whereClase, String whereArgs[], String groupBy,字符串具有,字符串 orderBy) {返回 myDataBase.query(tableName, tableColumns, whereClase, whereArgs,groupBy,具有,orderBy);}公共 ArrayList>selectRecordsFromDBList(String tableName, String[] tableColumns,String whereClase, String whereArgs[], String groupBy,字符串具有,字符串 orderBy) {ArrayList>retList = new ArrayList>();ArrayListlist = new ArrayList();Cursor cursor = myDataBase.query(tableName, tableColumns, whereClase, whereArgs,groupBy,具有,orderBy);如果 (cursor.moveToFirst()) {做 {list = new ArrayList();for(int i=0; i0;}public int updateRecordsInDB(String tableName,内容值初始值,字符串 whereClause,字符串 whereArgs[]) {返回 myDataBase.update(tableName, initialValues, whereClause, whereArgs);}public int deleteRecordInDB(String tableName, String whereClause,String[] whereArgs) {返回 myDataBase.delete(tableName, whereClause, whereArgs);}public Cursor selectRecordsFromDB(String query, String[] selectionArgs) {返回 myDataBase.rawQuery(query, selectionArgs);}公共 ArrayList>selectRecordsFromDBList(String query, String[] selectionArgs) {ArrayList>retList = new ArrayList>();ArrayListlist = new ArrayList();Cursor cursor = myDataBase.rawQuery(query, selectionArgs);如果 (cursor.moveToFirst()) {做 {list = new ArrayList();for(int i=0; i

HTC Desire 中的数据库锁定问题.>

如果插入表数据时出现任何问题,我想回滚.

请帮帮我

谢谢.

我看了同样的相关问题:

解决方案

实际上你做错了.如果您有多个记录要插入数据库或如果在其中一个数据库表中插入数据出现问题,则必须从其他表回滚数据.

例如

你有两张桌子

  1. A
  2. B

现在要在这两个表中插入数据,但是如果在表中插入数据时出现任何错误,则必须回滚事务.

现在你已经成功地在表A中插入数据,现在你正在尝试在表B中插入数据.现在如果在表B中插入数据时出错,则必须从表A中删除相关数据这意味着您必须回滚事务.

如何在 Android 中使用数据库事务

  1. 如果你想开始交易,有一个方法 beginTransaction()
  2. 如果你想提交事务,有一个方法 setTransactionSuccessful() 将提交数据库中的值
  3. 如果你已经开始交易你需要关闭交易所以有一个方法 endTransaction() 这将结束你的数据库事务

现在有两个要点

  1. 如果你想设置事务成功你需要写setTransactionSuccessful() 然后 endTransaction() 之后beginTransaction()
  2. 如果你想回滚你的交易,那么你需要endTransaction() 没有通过 setTransactionSuccessful().

您可以从此处

获得有关 SQLite 数据库事务的详细信息

就你而言

您可以在 try 和 catch 块中调用 saveCustomer() 函数

db.beginTransaction();尝试 {保存客户();db.setTransactionSuccessful();} 抓住 {//数据库事务之间的错误} 最后 {db.endTransaction();}

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 :

解决方案

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

这篇关于Android 数据库事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆