使用db.close()和db.setTransactionSuccessful()

时间:2016-08-24 11:38:00

标签: android sqlite

我正在处理的应用程序最初将有一个带有表的数据库,比如tbl_usr,它只有一个记录。基本上我们试图保持每个设备一个用户。当用户使用身份验证代码从设备登录时,他的详细信息将从服务器获取并存储在数据库中。下次如果他试图输入不同的验证码,这是有效的但不在表中,那么他将不被允许继续。以下是常见的DBHelper类。

但无论采用什么方法,我都会在第二次登录时尝试 databaselocked 异常。我已经提到了各种链接,其中建议在方法中使用database的不同实例,但它仍然带有错误。以下是我的助手课程

public class DBaseHelper extends SQLiteOpenHelper {
    private static String CREATE_TABLE;

    private static final String DATABASE_NAME="IPDB";
    private static String UserMessage="";
    private int tableType=0;

    private ContentValues cValues;

    private Cursor cursor;
    public enum TableTypes{
        Table1
    };

    public DBaseHelper(Context context){
        super(context,context.getExternalFilesDir(null).getAbsolutePath()+"/"+DATABASE_NAME,null,1);
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        TableTypes tableTypes=TableTypes.values()[tableType];
        switch (tableTypes){
            case Table1:
                CREATE_TABLE="CREATE TABLE IF NOT EXISTS tbl_usr....";
                break;
            default:
                break;
        }
        db.execSQL(CREATE_TABLE);
        db.close();
        System.out
                .println("onCreate Method Done.");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        /*db.execSQL("DROP TABLE IF EXISTS "+LOGIN_TABLE);*/
        onCreate(db);
    }

    /*this is the method which gets called from other class Like*/ 
    /*helper.insertRecord(tableParams);*/

    public HashMap<String,String> insertRecord(HashMap<String,String> dbaseParams){
        HashMap<String,String> response=new HashMap<String,String>();
        tableType=Integer.parseInt(dbaseParams.get("tableType"));
        cValues = new ContentValues();
        String TableName="";
        TableTypes tableTypes=TableTypes.values()[tableType];
        switch (tableTypes){
            case Table1:
                String AuthCode=dbParams.get("AuthCode");
                /*if user exists then check if its the same user*/
                if( CheckUserRecordExists(AuthCode) && empty(UserMessage) ){
                    response.put("isSuccess","true");
                    return response;
                }
                else {
                    if (!empty(UserMessage)) {
                        response.put("isSuccess", "false");
                        response.put("message",UserMessage);
                        return response;
                    }
                    /*add new user
                    Fill cValues declared above*/
                    TableName = "Table1";
                }
                break;
            default:
                break;
        }
        SQLiteDatabase dataBase = getWritableDatabase();
        /*insert data into database*/
        try {
           dataBase.beginTransaction();
           long rowID = dataBase.insertOrThrow(TableName, null, cValues);
           dataBase.setTransactionSuccessful();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
        finally {
            dataBase.close();
        }
        response.put("isSuccess", "true");
        return response;
    }

    private boolean CheckUserRecordExists(String authCode){
        UserMessage="";

        SQLiteDatabase dataBase=getReadableDatabase();
        /*Exception here when comes for 2nd time after new installation*/

        cursor = dataBase.query("Table1", new String[]{"COUNT(*)"}, null, null, null, null, null);
        cursor.moveToFirst();
        int iCount=cursor.getInt(0);
        /*check if any record exist*/
        if(iCount>0){
            dataBase.close();
            if(!cursor.isClosed()) cursor.close();
            /*check if the code entered matches with the record existing*/
            if(!CheckIsDataAlreadyInDBorNot("Table1","Auth_Code",authCode))
            {
                UserMessage="Invalid login!";
                return false;
            }
            else return true;
        }
        else{
            dataBase.close();
            if(!cursor.isClosed()) cursor.close();
            return false;
        }
    }

    private boolean CheckIsDataAlreadyInDBorNot( String TableName,
                                                      String dbfield, String fieldValue) {
        /*checking if user is same user*/
        SQLiteDatabase dataBase=getReadableDatabase();
        String[] columns = { dbfield };
        String selection = dbfield + " =?";
        String[] selectionArgs = { fieldValue };
        String limit = "1";

        Cursor cursor = dataBase.query(TableName, columns, selection, selectionArgs, null, null, null, limit);
        boolean exists = (cursor.getCount() > 0);
        cursor.close();
        dataBase.close();
        return exists;
    }
    public static boolean empty( final String s ) {
        return s == null || s.trim().isEmpty();
    }
}

我知道它的代码很庞大,但逻辑很简单。但问题是数据库锁定。有人能让我知道如何确保数据库在每次操作时始终处于有效状态吗?

1 个答案:

答案 0 :(得分:1)

您有beginTransaction()但没有与endTransaction()匹配的来电。正在进行的事务使数据库保持锁定状态,并使内部引用计数保持非零,因此close()尚未实际关闭数据库。

交易操作的传统模式是

db.beginTransaction();
try {
    // db operations that can throw

    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

同样在您的onCreate()中,您不应该关闭数据库,因为您不拥有它。