Я делаю некоторые тесты с моей фабрикой подключения к базе данных на Android.Проблемы с одновременным доступом к sqlitedatabase на 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();
}
}
}
мой DatabaseManager (я сделал этот класс для сценариев одновременного доступа к базе данных)
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 +" ======================");
}
}
мой класс тест:
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();
}
}
}
}
это работает отлично, но когда я использую транзакции , Я получаю за исключения:
@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:
Е/АКР (9850): java.lang.IllegalStateException: попытка повторно открыть без того замкнутого объекта: SQLiteDatabase: /data/data/seduc.ma.com.br .siaepmovel/баз данных/database.sqlite Е/АКРА (9850): в android.database.sqlite.SQLiteClosable.acquireReference (SQLiteClosable.java:55) E/АКРА (9850): в android.database.sqlite. SQLiteDatabase.beginTransaction (SQLiteDatabase.java:503) E/ACRA (9850): at android.database.sqlite.SQLiteDatabase.beginTransaction (SQLiteDatabase.java:416) E/ACRA (9 850): в seduc.ma.com.br.siaepmovel.test.TesteActivity $ Worker.run (TesteActivity.java:45)
любая идея, почему?
====
мои вопросы отличается тем, что проблема возникает только с транзакциями.
Простите меня, но вы, кажется, происходит из вашего пути, чтобы убедиться, что существует конфликт. – e4c5
Возможный дубликат [Параллельный доступ к базе данных SQLite в Android-db уже закрыт] (http://stackoverflow.com/questions/10801119/concurrent-access-to-a-sqlite-database-in-android-db- уже -closed) – e4c5
Почему вы не используете предоставленный SQLiteOpenHelper? http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html – Philio