SQLiteDatabaseLockedException:数据库已超过锁定的retrycount

时间:2014-09-24 11:16:29

标签: android sqlite memory-leaks

我正在进行Stock管理应用程序,它需要经常访问数据库才能查看和编辑数据。在多次重复此过程时,数据库会被锁定。

获得2错误: "数据库的SQLiteConnection对象泄露了!请修复您的应用程序以正确结束正在进行的事务,并在不再需要时关闭数据库。"

" SQLiteDatabaseLockedException:数据库被锁定(代码5):超出重试次数"

获取此错误后,需要很长时间才能完成数据库插入操作。

如何解决此问题。

public synchronized boolean insert(BeanOrderHeader orderHdrItem) throws Exception {
    boolean status=false;

    try {

        //Create Sqlite object to insert order details
        db = getSQLiteDatabase();

        //Before insert delete records if already exists
        deleteOrderData(db,orderHdrItem);

        db.beginTransactionNonExclusive();
        // db.beginTransaction();



        getPaymentPreparedStatement(db,orderHdrItem);


        status= true; 
        db.setTransactionSuccessful();

        db.endTransaction();


        if(orderHdrItem.isNewOrder())
            mCounterProvider.updateOrderBillNumber();

    } catch (Exception e) {

        e.printStackTrace();

        status= false;
        throw new Exception("Failed to save the order. Please check the log for details");
    }finally{
    db.setTransactionSuccessful();
    db.endTransaction();
    }
    return status;
}

 protected SQLiteDatabase getSQLiteDatabase() {
    if(myDataBase==null)
        open();

    if(!myDataBase.isOpen())
        open();
    return myDataBase;

}


  public SQLiteStatement getPaymentPreparedStatement(SQLiteDatabase db,BeanOrderHeader         
     orderHeader) throws Exception{
    ArrayList<BeanOrderPayment> orderPaymentlList=orderHeader.getOrderPaymentItems();
    SQLiteStatement prep;
    String insert_sql="insert into "+"order_payments "+" (" +               
            "order_id, "+                   
            "payment_mode, "+                   
            "paid_amount, "+                    
            "card_name, "+                  
            "card_type, "+                  
            "card_no, "+                    
            "name_on_card, "+               
            "card_expiry_month, "+                  
            "card_expiry_year, "+                   
            "card_approval_code, "+ 
            "card_account_type, "+
            "company_id, "+                 
            "voucher_id, "+                 
            "voucher_value, "+                  
            "voucher_count, "+                  
            "cashier_id, "+ 
            "payment_date, " +
            "payment_time "+                    
            ",id " +
            ",discount_id" +
            ",discount_code" +
            ",discount_name" +
            ",discount_description" +
            ",discount_price" +
            ",discount_is_percentage" +
            ",discount_is_overridable" +
            ",discount_amount" +
            ",is_repayment" +
            ",is_voucher_balance_returned" +
            ",partial_balance" +
            ") "+
            " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    prep=db.compileStatement(insert_sql);
    int counter=0;
    if(mPosOrderUtil==null)
    mPosOrderUtil=new PosOrderUtil(getContext());
    for (BeanOrderPayment payItem: orderPaymentlList){  
        prep.bindString(1, payItem.getOrderId());
        prep.bindLong(2, payItem.getPaymentMode().getValue());
        prep.bindDouble(3, payItem.getPaidAmount());
        prep.bindString(4, payItem.getCardName());
        prep.bindString(5, payItem.getCardType());
        prep.bindString(6, payItem.getCardNo());
        prep.bindString(7, payItem.getNameOnCard());
        prep.bindLong(8, payItem.getCardExpiryMonth());
        prep.bindLong(9, payItem.getCardExpiryYear());
        prep.bindString(10, payItem.getCardApprovalCode());
        prep.bindString(11, payItem.getAccount());
        prep.bindLong(12, payItem.getCompanyId());
        prep.bindLong(13, payItem.getVoucherId());
        prep.bindDouble(14, payItem.getVoucherValue());
        prep.bindLong(15, payItem.getVoucherCount());
        prep.bindLong(16, payItem.getCashierID());
        prep.bindString(17, payItem.getPaymentDate());
        prep.bindString(18, payItem.getPaymentTime());
        prep.bindString(19, mPosOrderUtil.appendToId(orderHeader.getOrderId(), counter++)); //Id generated from order id
        BeanDiscount disc=payItem.getDiscount();
        if(disc!=null){
            prep.bindLong(20, disc.getId());
            prep.bindString(21, disc.getCode());
            prep.bindString(22, disc.getName());
            prep.bindString(23, disc.getDescription());
            prep.bindDouble(24, disc.getPrice());
            prep.bindLong(25, getIntFromBoolean(disc.isPercentage()));
            prep.bindLong(26, getIntFromBoolean(disc.isOverridable()));
            prep.bindDouble(27, payItem.getPaidAmount());
        }
        prep.bindLong(28, getIntFromBoolean(payItem.isRepayment()));
        prep.bindLong(29, getIntFromBoolean(payItem.isVoucherBalanceReturned()));
        prep.bindDouble(30, payItem.getPartialBalance());
        prep.executeInsert();
        prep.clearBindings();
    }   
    return prep;
} 

3 个答案:

答案 0 :(得分:2)

您需要在db操作

之后关闭SQLiteHelper类实例
dbHelper.close()

答案 1 :(得分:0)

最后,我通过保留SQLiteDatabase实例的单个对象来解决问题。如果数据库结构很复杂,使用单个对象访问所有表中的数据,这样我们就可以轻松管理sq-lite数据库。

db操作后关闭数据库对象以解决数据库泄漏问题

 mDatabase.close()

答案 2 :(得分:0)

此SQLiteDatabaseLockedException的另一个原因是启动一个事务,而不是在finally块中关闭它,后来尝试对DB执行某些操作。

为:

 SQLiteDatabase db = this.getReadableDatabase();
 db.beginTransaction();
 //DO some db writing
 db.setTransactionSuccessful();
 db.endTransaction();

好:

 SQLiteDatabase db = this.getReadableDatabase();
 db.beginTransaction();
 try {
   //DO some db writing
   db.setTransactionSuccessful();
 } finally {
    db.endTransaction();
 }
相关问题