I am making some tests with my database connection factory on Android.
public class ConnectionFactory {
    private Context context;
    private SQLiteDatabase w;
    private static DatabaseManager manager;
    public ConnectionFactory(Context context) {
        this.context = context;
    }
    public synchronized SQLiteDatabase getDatabase(){
        if(manager == null){
            DatabaseManager.init(new DatabaseHelper(context));
            manager = DatabaseManager.getInstance();
        }
        return w == null || !w.isOpen() ? w = manager.getDatabase() : w;
    }
    public synchronized void close() {
        if(w != null && w.isOpen()){
            manager.close();
        }
    }
}
my DatabaseManager (I made this class for scenarios of concurrent access to database)
public class DatabaseManager {
    private static SQLiteOpenHelper helper;
    private static DatabaseManager instance;
    private static int COUNTER = 0;
    private SQLiteDatabase database;
    private DatabaseManager(){}
    public static synchronized void init(SQLiteOpenHelper first) {
        if (instance == null) {
            helper = first;
            instance = new DatabaseManager(){
                @Override
                protected void finalize() throws Throwable {
                    helper.close();
                    COUNTER = 0;
                    helper = null;
                }
            };
        }
    }
    public static synchronized DatabaseManager getInstance() {
        if (instance == null) {
            throw new IllegalStateException("O método init deve ser chamado antes deste método.");
        }
        return instance;
    }
    public synchronized SQLiteDatabase getDatabase() {
        COUNTER++;
        if(COUNTER == 1) {
            Log.i("SIAEP", "====================== ABRINDO UMA NOVA REFERENCIA DE SQLITEDATABASE ======================");
            database = helper.getWritableDatabase();
        }
        Log.i("SIAEP", "====================== DATABASE MANAGER COUNTER 'getDatabase': "+ COUNTER +" ======================");
        return database;
    }
    public synchronized void close() {
        if(COUNTER != 0)
            COUNTER--;
        if(COUNTER == 0) {
            if(database.inTransaction()){
                database.endTransaction();
            }
            Log.i("SIAEP", "====================== FECHANDO A REFERENCIA DE SQLITEDATABASE ======================");
            database.close();
        }
        Log.i("SIAEP", "====================== DATABASE MANAGER COUNTER 'close': "+ COUNTER +" ======================");
    }
}
my class of test:
public class TesteActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Worker t1 = new Worker(this);
        Worker t2 = new Worker(this);
        t1.start();
        t2.start();
    }
    public static class Worker extends Thread {
        private Activity instance;
        public Worker(Activity instance) {
            this.instance = instance;
        }
        @Override
        public void run() {
            ConnectionFactory factory = new ConnectionFactory(instance);
            for (int i = 0; i < 100; i++) {
                SQLiteDatabase database = factory.getDatabase();
                factory.close();
            }
        }
    }
}
this works perfectly, but when I use transactions, I receive some exceptions:
    @Override
    public void run() {
        ConnectionFactory factory = new ConnectionFactory(instance);
        for (int i = 0; i < 100; i++) {
            SQLiteDatabase database = factory.getDatabase();
            database.beginTransaction();
            database.setTransactionSuccessful();
            database.endTransaction();
            factory.close();
        }
    }
excetion:
E/ACRA ( 9850): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/seduc.ma.com.br.siaepmovel/databases/database.sqlite E/ACRA ( 9850): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55) E/ACRA ( 9850): at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:503) E/ACRA ( 9850): at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416) E/ACRA ( 9850): at seduc.ma.com.br.siaepmovel.test.TesteActivity$Worker.run(TesteActivity.java:45)
any idea why?
====
my questions is different because the problem occurs only with transactions.