본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] Concurrent Database Access

by 돼지왕 왕돼지 2014. 8. 17.
반응형


 [android] Concurrent Database Access

 


[android] Concurrent Database Access


https://github.com/dmytrodanylyk/dmytrodanylyk/blob/gh-pages/articles/Concurrent%20Database%20Access.md


새로운 SQLiteOpenHelper 를 만들면, 이것은 새로운 database connection 을 만드는 것이다.

다른 connection 에서 동시에 한 db 에 write 를 시도하면, 한쪽은 lock 문제로 fail 한다.


여러 Thread 에서 동시에 db 작업을 할 경우에는 반드시 한 connection 을 사용하도록 유도해야 한다.


이 때 주의할 것은 각각의 thread 에서 db.close() 를 호출할 경우 

한 connection 의 getDatabase() 는 같은 instance 를 반환하기 때문에 다음 에러를 마딱뜨릴 수 있다.


java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase


그렇다고 close 를 안 시키면 아래의 에러를 마딱뜨리게 될 것이다.


Leak found Caused by: java.lang.IllegalStateException: SQLiteDatabase created and never closed


다음과 같은 방법으로 close 해야 안전하다.


public class DatabaseManager {


    private AtomicInteger mOpenCounter = new AtomicInteger();


    private static DatabaseManager instance;

    private static SQLiteOpenHelper mDatabaseHelper;

    private SQLiteDatabase mDatabase;


    public static synchronized void initializeInstance(SQLiteOpenHelper helper) {

        if (instance == null) {

            instance = new DatabaseManager();

            mDatabaseHelper = helper;

        }

    }


    public static synchronized DatabaseManager getInstance() {

        if (instance == null) {

            throw new IllegalStateException(DatabaseManager.class.getSimpleName() +

                    " is not initialized, call initializeInstance(..) method first.");

        }


        return instance;

    }


    public synchronized SQLiteDatabase openDatabase() {

        if(mOpenCounter.incrementAndGet() == 1) {

            // Opening new database

            mDatabase = mDatabaseHelper.getWritableDatabase();

        }

        return mDatabase;

    }


    public synchronized void closeDatabase() {

        if(mOpenCounter.decrementAndGet() == 0) {

            // Closing database

            mDatabase.close();


        }

    }

}







반응형

댓글