2010-12-16 2 views
38

Wo soll ich close() auf den Code aufrufen?Android Fehler - close() wurde nie explizit auf Datenbank

Die LogCat gibt diesen Fehler zurück:

close() was never explicitly called on database android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

Der Fehler ist dies:

> 12-16 17:24:50.886: ERROR/Database(10982): close() was never explicitly called on database '/data/data/com.psyhclo/databases/calls.db' 
12-16 17:24:50.886: ERROR/Database(10982): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
12-16 17:24:50.886: ERROR/Database(10982):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1827) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:854) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:847) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:541) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118) 
12-16 17:24:50.886: ERROR/Database(10982):  at com.psyhclo.CallDataHelper.<init>(CallDataHelper.java:27) 
12-16 17:24:50.886: ERROR/Database(10982):  at com.psyhclo.RatedCalls.fillList(RatedCalls.java:66) 
12-16 17:24:50.886: ERROR/Database(10982):  at com.psyhclo.RatedCalls.access$0(RatedCalls.java:63) 
12-16 17:24:50.886: ERROR/Database(10982):  at com.psyhclo.RatedCalls$RatedCallsContentObserver.onChange(RatedCalls.java:58) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:43) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.os.Handler.handleCallback(Handler.java:587) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.os.Handler.dispatchMessage(Handler.java:92) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.os.Looper.loop(Looper.java:123) 
12-16 17:24:50.886: ERROR/Database(10982):  at android.app.ActivityThread.main(ActivityThread.java:3647) 
12-16 17:24:50.886: ERROR/Database(10982):  at java.lang.reflect.Method.invokeNative(Native Method) 
12-16 17:24:50.886: ERROR/Database(10982):  at java.lang.reflect.Method.invoke(Method.java:507) 
12-16 17:24:50.886: ERROR/Database(10982):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
12-16 17:24:50.886: ERROR/Database(10982):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
12-16 17:24:50.886: ERROR/Database(10982):  at dalvik.system.NativeStart.main(Native Method) 

hier mein Code.

Die Aktivität:

public class RatedCalls extends ListActivity { 

private static final String LOG_TAG = "RATEDCALLSOBSERVER"; 
private Handler handler = new Handler(); 
private SQLiteDatabase db; 
private CallDataHelper cdh; 
StringBuilder sb = new StringBuilder(); 
OpenHelper openHelper = new OpenHelper(RatedCalls.this); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    registerContentObservers(); 
    Log.d("FILLLIST", "calling from onCreate()"); 

} 

class RatedCallsContentObserver extends ContentObserver { 
    public RatedCallsContentObserver(Handler h) { 
     super(h); 
    } 

    @Override 
    public boolean deliverSelfNotifications() { 
     return true; 

    } 

    @Override 
    public void onChange(boolean selfChange) { 
     Log.d(LOG_TAG, "RatedCallsContentObserver.onChange(" + selfChange 
       + ")"); 
     super.onChange(selfChange); 
     fillList(); 
     onStop(); 
    } 
} 

private void fillList() { 

    db = openHelper.getWritableDatabase(); 
    cdh = new CallDataHelper(this); 
    String lastDate = cdh.selectDate(); 

    Cursor cursor = getContentResolver().query(
      android.provider.CallLog.Calls.CONTENT_URI, null, 
      android.provider.CallLog.Calls.DATE + " < ?", 
      new String[] { lastDate }, 
      android.provider.CallLog.Calls.DATE + " DESC "); 

    Log.d("FILLLIST", "Calling from filllist"); 

    startManagingCursor(cursor); 
    int numberColumnId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.NUMBER); 
    int durationId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.DURATION); 
    int contactNameId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);   
    int numTypeId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE); 

    Date dt = new Date(); 
    int hours = dt.getHours(); 
    int minutes = dt.getMinutes(); 
    int seconds = dt.getSeconds(); 
    String currTime = hours + ":" + minutes + ":" + seconds; 

    SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy"); 
    Date date = new Date(); 

    ArrayList<String> callList = new ArrayList<String>(); 
    cursor.moveToFirst(); 

    String contactNumber = cursor.getString(numberColumnId); 
    String contactName = cursor.getString(contactNameId); 
    String duration = cursor.getString(durationId); 
    // String callDate = DateFormat.getDateInstance().format(dateId); 
    String numType = cursor.getString(numTypeId); 

    ContentValues values = new ContentValues(); 

    values.put("contact_id", 1); 
    values.put("contact_name", contactName); 
    values.put("number_type", numType); 
    values.put("contact_number", contactNumber); 
    values.put("duration", duration); 
    values.put("date", dateFormat.format(date)); 
    values.put("current_time", currTime); 
    values.put("cont", 1); 
    getBaseContext().getContentResolver().notifyChange(
      android.provider.CallLog.Calls.CONTENT_URI, 
      new RatedCallsContentObserver(handler)); 
    db.insert(CallDataHelper.TABLE_NAME, null, values); 
    Toast.makeText(getBaseContext(), "Inserted!", Toast.LENGTH_LONG); 
    callList.add("Contact Number: " + contactNumber + "\nContact Name: " 
      + contactName + "\nDuration: " + duration + "\nDate: " 
      + dateFormat.format(date)); 

    setListAdapter(new ArrayAdapter<String>(this, R.layout.listitem, 
      callList)); 
    ListView lv = getListView(); 
    lv.setTextFilterEnabled(true); 

    lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 

      Toast.makeText(getApplicationContext(), 
        ((TextView) view).getText(), Toast.LENGTH_SHORT).show(); 

     } 
    }); 
} 

public void registerContentObservers() { 

    this.getApplicationContext() 
      .getContentResolver() 
      .registerContentObserver(
        android.provider.CallLog.Calls.CONTENT_URI, true, 
        new RatedCallsContentObserver(handler)); 

} 

public void unregisterContentObservers() { 

    this.getApplicationContext() 
      .getContentResolver() 
      .unregisterContentObserver(
        new RatedCallsContentObserver(handler)); 

} 
    } 

Und die DatabaseHelper

public class CallDataHelper { 

private static final String DATABASE_NAME = "calls.db"; 
private static final int DATABASE_VERSION = 1; 
protected static final String TABLE_NAME = "contact_data"; 

private Context context; 
private SQLiteDatabase db; 

public CallDataHelper(Context context) { 
    this.context = context; 
    OpenHelper openHelper = new OpenHelper(this.context); 
    this.db = openHelper.getWritableDatabase(); 
} 

public boolean insert(Integer cId, String cName, String numType, 
     String cNum, String dur, String date, String currTime) { 
    this.db.execSQL("insert into " 
      + TABLE_NAME 
      + " (contact_id, contact_name, number_type, contact_number, duration, date, current_time, cont) " 
      + " values(" + cId + ", " + cName + ", " + numType + ", " 
      + cNum + ", " + dur + ", " + date + ", " + currTime + ", 1)"); 
    return true;   
} 

public void update(String word) { 
    this.db.execSQL("UPDATE words SET cont = cont + 1 WHERE (word= ?)", 
      new String[] { word }); 
} 

public void deleteAll() { 
    this.db.delete(TABLE_NAME, null, null); 
} 

public String selectDate() { 

    String date = ""; 
    Cursor cursor = this.db.query(TABLE_NAME, new String[] { "date" }, 
      "id = ?", new String[] { "max(id)" }, null, null, null); 
    if (cursor.moveToFirst()) { 
     do { 
      date = cursor.getString(0); 
     } while (cursor.moveToNext()); 
    } 
    if (cursor != null && !cursor.isClosed()) { 
     cursor.close(); 
     return date; 
    } else { 
     return ""; 
    } 
} 

public List<String> selectAll() { 
    List<String> list = new ArrayList<String>(); 
    Cursor cursor = this.db.query(TABLE_NAME, new String[] { "word" }, 
      null, null, null, null, "cont desc"); 
    if (cursor.moveToFirst()) { 
     do { 
      list.add(cursor.getString(0).toUpperCase()); 
     } while (cursor.moveToNext()); 
    } 
    if (cursor != null && !cursor.isClosed()) { 
     cursor.close(); 
    } 
    return list; 
} 

public static class OpenHelper extends SQLiteOpenHelper { 

    OpenHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL("CREATE TABLE " 
       + TABLE_NAME 
       + "(id INTEGER PRIMARY KEY AUTOINCREMENT, contact_id INTEGER, contact_name VARCHAR(50), number_type VARCHAR(50), contact_number VARCHAR(50), duration TIME, date DATE, current_time TIME, cont INTEGER)"); 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w("RatedCalls Database", 
       "Upgrading database, this will drop tables and recreate."); 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
     onCreate(db); 
    } 
} 
    } 

_ ___ (Edited) __ _ ____

Das ist, was ich jetzt bekomme. Wenn ich einen neuen Anruf tätige, gibt Logcat das zurück.

12-16 18:55:27.365: ERROR/AndroidRuntime(767): FATAL EXCEPTION: main 
12-16 18:55:27.365: ERROR/AndroidRuntime(767): java.lang.IllegalStateException: database not open 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1230) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1189) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1271) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at com.psyhclo.CallDataHelper.selectDate(CallDataHelper.java:61) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at com.psyhclo.RatedCalls.fillList(RatedCalls.java:98) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at com.psyhclo.RatedCalls.access$0(RatedCalls.java:96) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at com.psyhclo.RatedCalls$RatedCallsContentObserver.onChange(RatedCalls.java:91) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:43) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at android.os.Handler.handleCallback(Handler.java:587) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at android.os.Handler.dispatchMessage(Handler.java:92) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at android.os.Looper.loop(Looper.java:123) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at android.app.ActivityThread.main(ActivityThread.java:3647) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at java.lang.reflect.Method.invokeNative(Native Method) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at java.lang.reflect.Method.invoke(Method.java:507) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
12-16 18:55:27.365: ERROR/AndroidRuntime(767):  at dalvik.system.NativeStart.main(Native Method) 

Und das ist meine Tätigkeit:

public class RatedCalls extends ListActivity { 

private static final String LOG_TAG = "RATEDCALLSOBSERVER"; 
private Handler handler = new Handler(); 
private SQLiteDatabase db; 
private CallDataHelper cdh; 
StringBuilder sb = new StringBuilder(); 
OpenHelper openHelper = new OpenHelper(RatedCalls.this); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    registerContentObservers(); 
    Log.d("FILLLIST", "calling from onCreate()"); 
    cdh = new CallDataHelper(this); 
    db = openHelper.getWritableDatabase(); 

} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    if (openHelper != null) { 
     openHelper.close(); 
    } 
    if (cdh != null) { 
     cdh.close(); 
    } 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    if (openHelper != null) { 
     openHelper.close(); 
    } 
    if (cdh != null) { 
     cdh.close(); 
    } 
} 

@Override 
public void onResume() { 

    super.onResume(); 
    openOrCreateDatabase("calls.db", SQLiteDatabase.CREATE_IF_NECESSARY, 
      null); 

} 

class RatedCallsContentObserver extends ContentObserver { 
    public RatedCallsContentObserver(Handler h) { 
     super(h); 
    } 

    @Override 
    public boolean deliverSelfNotifications() { 
     return true; 

    } 

    @Override 
    public void onChange(boolean selfChange) { 
     Log.d(LOG_TAG, "RatedCallsContentObserver.onChange(" + selfChange 
       + ")"); 
     super.onChange(selfChange); 
     fillList(); 

    } 
} 

private void fillList() { 

    String lastDate = cdh.selectDate(); 

    Cursor cursor = getContentResolver().query(
      android.provider.CallLog.Calls.CONTENT_URI, null, 
      android.provider.CallLog.Calls.DATE + " < ?", 
      new String[] { lastDate }, 
      android.provider.CallLog.Calls.DATE + " DESC "); 

    Log.d("FILLLIST", "Calling from filllist"); 

    startManagingCursor(cursor); 
    int numberColumnId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.NUMBER); 
    int durationId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.DURATION); 
    int contactNameId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME); 
    int numTypeId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE); 

    Date dt = new Date(); 
    int hours = dt.getHours(); 
    int minutes = dt.getMinutes(); 
    int seconds = dt.getSeconds(); 
    String currTime = hours + ":" + minutes + ":" + seconds; 

    SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy"); 
    Date date = new Date(); 

    ArrayList<String> callList = new ArrayList<String>(); 
    cursor.moveToFirst(); 

    String contactNumber = cursor.getString(numberColumnId); 
    String contactName = cursor.getString(contactNameId); 
    String duration = cursor.getString(durationId); 
    // String callDate = DateFormat.getDateInstance().format(dateId); 
    String numType = cursor.getString(numTypeId); 
    stopManagingCursor(cursor); 
    ContentValues values = new ContentValues(); 

    values.put("contact_id", 1); 
    values.put("contact_name", contactName); 
    values.put("number_type", numType); 
    values.put("contact_number", contactNumber); 
    values.put("duration", duration); 
    values.put("date", dateFormat.format(date)); 
    values.put("current_time", currTime); 
    values.put("cont", 1); 
    getBaseContext().getContentResolver().notifyChange(
      android.provider.CallLog.Calls.CONTENT_URI, 
      new RatedCallsContentObserver(handler)); 
    db.insert(CallDataHelper.TABLE_NAME, null, values); 
    Toast.makeText(getBaseContext(), "Inserted!", Toast.LENGTH_LONG); 
    callList.add("Contact Number: " + contactNumber + "\nContact Name: " 
      + contactName + "\nDuration: " + duration + "\nDate: " 
      + dateFormat.format(date)); 

    setListAdapter(new ArrayAdapter<String>(this, R.layout.listitem, 
      callList)); 
    ListView lv = getListView(); 
    lv.setTextFilterEnabled(true); 

    lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 

      Toast.makeText(getApplicationContext(), 
        ((TextView) view).getText(), Toast.LENGTH_SHORT).show(); 

     } 
    }); 
} 

public void registerContentObservers() { 

    this.getApplicationContext() 
      .getContentResolver() 
      .registerContentObserver(
        android.provider.CallLog.Calls.CONTENT_URI, true, 
        new RatedCallsContentObserver(handler)); 

} 

public void unregisterContentObservers() { 

    this.getApplicationContext() 
      .getContentResolver() 
      .unregisterContentObserver(
        new RatedCallsContentObserver(handler)); 

} 
} 

Antwort

46

Ich denke, das Problem ist, dass Sie die db, wenn Ihre Aktivität zerstört wird schließen müssen. Versuchen Sie, diese zu Ihrer Aktivität:

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    if (openHelper != null) { 
     openHelper.close(); 
    } 
    if (cdh != null) { 
     cdh.close(); 
    } 
} 

und fügen Sie diese zu Ihrer CallDataHelper Klasse:

public void close() { 
    // NOTE: openHelper must now be a member of CallDataHelper; 
    // you currently have it as a local in your constructor 
    if (openHelper != null) { 
     openHelper.close(); 
    } 
} 

EDIT 2: Auch die CallDataHelper Konstruktor ändern:

// Declare openHelper as a member variable 
OpenHelper openHelper = null; 

public CallDataHelper(Context context) { 
    this.context = context; 
    openHelper = new OpenHelper(this.context); 
    this.db = openHelper.getWritableDatabase(); 
} 

Dies sollte Schließen Sie erfolgreich die Datenbankverbindung, die von beiden Ihrer OpenHelper Instanzen erstellt wurde.

(EDITED um die Tatsache widerzuspiegeln, dass Sie zwei verwenden OpenHelper Instanzen.)

+0

Ich habe es getan, und nach einiger Zeit die Anwendung ausgeführt wurde, ist der Fehler: 12-16 18: 09: 47,406: ERROR/Datenbank (21184): android.database.sqlite.DatabaseObjectNotClosedException: Anwendung nicht schließen der Cursor oder das Datenbankobjekt, das hier geöffnet wurde Ich denke, es ist der Cursor, der geschlossen werden muss. Wie kann ich es schließen? – rogcg

+0

@psychclo: Hast du meinen Schnitt gesehen? Sie haben zwei OpenHelper-Instanzen, von denen jede eine DB-Verbindung verwendet, so dass beide geschlossen werden müssen. (Sie könnten diese beiden OpenHelpers kombinieren; das ist Ihr Aufruf.) –

+0

Die Methode close() muss innerhalb der Klasse OpenHelper oder CallDataHelper sein. Das openHelper-Feld ist auf CallDataHelper, aber wenn ich versuche, die Methode zu schließen, heißt das: openHelper kann nicht in eine Variable aufgelöst werden. Und bietet an, das Feld zu erstellen. Obs: Ich erkläre die Methode close() auf CallDataHelper. Und wenn ich versuche, so zu tun: public void close() { \t \t // HINWEIS: openHelper muss jetzt ein Mitglied von CallDataHelper sein; \t // Sie haben es zur Zeit als lokal in Ihrem Konstruktor \t if (this.db! = Null) { \t \t this.db.close(); \t} – rogcg

1

Ich vermute fillList() wird mehrmals während einer RatedCalls „Sitzung“ bezeichnet. Also jedes Mal, wenn Sie eine neue Cursor Instanz erstellen und startManagingCursor() darauf aufrufen. Auf diese Weise sammeln Sie eine Liste von Cursor - ArrayList<ManagedCursor> um genau zu sein, die in ListActivity deklariert ist. Normalerweise werden sie (Cursor, die verwaltet werden) automatisch in ListActivity.onDestroy() geschlossen. Können Sie bestätigen, RatedCalls tatsächlich übergibt onDestroy().

Überschreiben Sie irgendwie die in RatedCalls. Wenn ja, rufen Sie dann super.onDestroy() (Sie sollten es nennen)?

Ich bekomme nicht den Zweck des Aufrufs onStop() in RatedCallsContentObserver.onChange() nach der fillList();. Ich glaube, Activity Life-Cycle Callbacks sollten von OS nur aufgerufen werden. Also vielleicht einen Call-Back-Lifecycle manuell aufrufen Sie irgendwie verhindern, von onDestroy() von OS aufgerufen werden (nur eine Vermutung)?

UPDATE:

Dan Breslau ist richtig - es ist db Objekt, das nicht geschlossen ist. Entschuldigung für die Irreführung.

+0

Die Stack-Traces zeigen, dass das nicht geschlossene Objekt die Datenbankverbindung selbst ist, die über 'SQLiteOpenHelper.getWritableDatabase' zurückgegeben wird. Obwohl 'startManagingCursor' sicherstellt, dass der Cursor ordnungsgemäß entsorgt wird, ist mir nichts bekannt, was automatisch Datenbankverbindungen schließen würde, wenn die Aktivität zerstört wird. (Mein Mangel an Bewusstsein ist jedoch nicht definitiv :-) –

+0

@Dan Breslau: OMG, du hast Recht !!! es ist "call.db", das nicht geschlossen ist! Als ich das erste Mal die Frage öffnete, war die Stack-Trace nicht gut formatiert, also habe ich das wahrscheinlich übersehen. –

+0

@Arhimed deine Antwort ist völlig richtig. Ich wusste, dass das passierte, ich wusste einfach nicht, wie ich das lösen sollte. In der Tat ist die ursprüngliche Frage diese http://stackoverflow.com/questions/4450778/android-contentobserver-no-stoped, und diese Frage, die wir jetzt sind, kam von dieser Antwort für diese Frage. Was soll ich tun, damit fillList() während einer "Session" von RatedCalls mehrmals aufgerufen wird? Mann, du hast meine Gedanken geöffnet! Vielen Dank. – rogcg

2

Wörtlich verstehen Datenbank ist normalerweise nicht geschlossen, die tatsächliche, weil wiederholte Instanziierung Ihrer Datenbank, oder verbinden Sie wurden eingerichtet, und Sie und versuchen, eine andere Verbindung dort zu öffnen wird keine Ausnahme sein. Also die Lösung ist, stellen Sie sicher, dass Sie nur eine Verbindung öffnen.