2012-03-02 3 views
0

각각의 데이터베이스 테이블을 담당하는 일련의 클래스가있는 프로젝트가 있습니다.데이터베이스가 잠겨있어 Android onUpgrade()가 실패합니다. 어떻게해야합니까?

public class PersonManager { 

    SQLiteDatabase db; 
    DbAdapter dbAdapter; //This is a subclass of SQLiteOpenHelper 

    public void addPerson(Person person) 
    { 
     ContentValues contentValues = new ContentValues(); 
     contentValues.put("email", person.email); 
     contentValues.put("first_name", person.firstName); 

     db = dbAdapter.getWritableDatabase(); 
     db.insert("person", null, contentValues); 
     db.close(); 
    } 

    ...other crud/utility methods omitted... 
} 
이제

내가 onUpgrade()를 통해 내 데이터베이스를 업그레이드 오전, 나는 데이터베이스에 실행 잠긴 :

각 테이블 관리 클래스는 연결을 얻을의 패턴을 따라 CRUD 방법, 실행 침전물 운영, 가까운 연결을 포함 문제.

정확한 오류 메시지는 다음과 같습니다

CREATE TABLE android_metadata failed 
Failed to setLocale() when constructing, closing the database 
android.database.sqlite.SQLiteException: database is locked 

onUpgrade이에 의미 중 하나 나타납니다 :

1 run db.execSQL() calls or 
2 use helper classes that use onUpgrade()'s SQLiteDatabase rather than their own 

(onUpgrade에 데이터를 마이그레이션하는 클래스를 관리하는 내 테이블을 사용하는 것이 훨씬 쉬울 것)보다 db.execSQL() 문을 사용하거나, 모든 CRUD 메소드를 다시 작성하여 onUpgrade()의 SQLiteDatabase를 사용할 수 있습니다.

데이터베이스 액세스가 올바르게 설정되어 있습니까? 위의 코드가 올바른 패턴을 따른다면이 문제를 해결하기 위해 무엇을해야합니까?

감사합니다.

+0

이전에이 문제가 발생했습니다. 범위를 좁히는 데 도움이되는 몇 가지 질문, 스레딩을 수행하고 있습니까?이 인스턴스에서 SQLiteOpenHelper가 싱글 톤입니까? 하나의 액세스 포인트 만 있어야합니다 (http://stackoverflow.com/a/3689883/429047). –

+0

SQLiteOpenHelper를 확장하는 클래스가 있습니다. 정적 인스턴스를 반환하는 대신이 클래스를 인스턴스화합니다. Context reference를 singleton에 전달하는 것이 괜찮습니까? 또한 각 CRUD 메소드에서 연결을 열고 닫습니다. – Shellum

+0

내가 이해할 수없는 것은 업그레이드시 특정 테이블에서 실패하는 이유입니다. 업그레이드하기 전에 android_metadata가 있어야합니다. 도우미로부터 onUpgrade 메소드를 게시 할 수 있습니까? –

답변

1

답변을 얻지 못했습니다. 그래서 개발자 행 아웃에 대해 질문했습니다.

Android 개발자 행 아웃 팀에 따르면 onUpgrade는 구조 변경에만 사용되며 데이터 이전/조작에는 해당되지 않습니다. 당신이 onUpgrade()에있을 때, 당신은의 SQLiteDatabase가 onUpgrade()가 당신을 제공하는 처리 사용할 필요가

db = dbAdapter.getWritableDatabase(); 

:

2

는 여기에 귀하의 문제입니다. 그래서 솔루션이 하나 더 인수를 위해 addPerson 기능을 재 작성하는 것입니다 -의 SQLiteDatabase 핸들을 : 당신이 다른 프로젝트에서에서 addPerson()를 호출해야하는 경우

public void addPerson(Person person, SQLiteDatabase db) {...} 

후 현재 addPerson (사람 사람)를 유지 함수를 호출하면 db = dbAdapter.getWritableDatabase() 이 호출되고 addPerson()의 두 인수 버전에 db가 전달됩니다.